diff --git a/.mvn/maven.config b/.mvn/maven.config deleted file mode 100644 index 39d4ab0e..00000000 --- a/.mvn/maven.config +++ /dev/null @@ -1 +0,0 @@ ---settings ./.mvn/settings.xml \ No newline at end of file diff --git a/.mvn/settings.xml b/.mvn/settings.xml deleted file mode 100755 index 26bf1655..00000000 --- a/.mvn/settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/domino-jackson-processor/pom.xml b/domino-jackson-processor/pom.xml index 14c4b931..d6cdc75a 100644 --- a/domino-jackson-processor/pom.xml +++ b/domino-jackson-processor/pom.xml @@ -6,7 +6,7 @@ org.dominokit domino-jackson-parent - 1.0.0 + 1.0.1 domino-jackson-processor @@ -27,7 +27,7 @@ com.google.guava guava - 31.1-jre + 32.0.1-jre org.apache.commons diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/AbstractMapperGenerator.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/AbstractMapperGenerator.java index 9af5da51..71a25401 100644 --- a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/AbstractMapperGenerator.java +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/AbstractMapperGenerator.java @@ -60,29 +60,36 @@ public void generate(Element element) throws IOException { Name beanName = typeUtils.asElement(beanType).getSimpleName(); generateJsonMappers(beanType); + if (!GeneratedMappersRegistry.INSTANCE.hasTypeToken(getCategory(), beanType)) { + GeneratedMappersRegistry.INSTANCE.addTypeToken(getCategory(), beanType); - TypeSpec.Builder builder = - TypeSpec.classBuilder(className) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .superclass(abstractObjectMapper(element)) - .addField( - FieldSpec.builder(ClassName.bestGuess(className), "INSTANCE") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) - .initializer( - CodeBlock.builder().add("new $T()", ClassName.bestGuess(className)).build()) - .build()) - .addMethod(makeConstructor(beanName)) - .addMethods(getMapperMethods(element, beanType)); + TypeSpec.Builder builder = + TypeSpec.classBuilder(className) + .addModifiers(Modifier.PUBLIC, Modifier.FINAL) + .superclass(abstractObjectMapper(element)) + .addField( + FieldSpec.builder(ClassName.bestGuess(className), "INSTANCE") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + .initializer( + CodeBlock.builder() + .add("new $T()", ClassName.bestGuess(className)) + .build()) + .build()) + .addMethod(makeConstructor(beanName)) + .addMethods(getMapperMethods(element, beanType)); - if (useInterface(element)) { - builder.addSuperinterface(TypeName.get(element.asType())); - } + if (useInterface(element)) { + builder.addSuperinterface(TypeName.get(element.asType())); + } - TypeSpec classSpec = builder.build(); + TypeSpec classSpec = builder.build(); - JavaFile.builder(packageName, classSpec).build().writeTo(filer); + JavaFile.builder(packageName, classSpec).build().writeTo(filer); + } } + protected abstract GeneratedMappersRegistry.Category getCategory(); + protected static TypeMirror getElementType(Element element) { if (useInterface(element)) { TypeMirror objectReader = diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanMapperGenerator.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanMapperGenerator.java index e2105abf..2369535b 100644 --- a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanMapperGenerator.java +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanMapperGenerator.java @@ -60,4 +60,9 @@ protected void generateSerializer(TypeMirror beanType) { protected void generateDeserializer(TypeMirror beanType) { new DeserializerGenerator().generate(beanType); } + + @Override + protected GeneratedMappersRegistry.Category getCategory() { + return GeneratedMappersRegistry.Category.MAPPER; + } } diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanReaderGenerator.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanReaderGenerator.java index 618fa308..252ac299 100644 --- a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanReaderGenerator.java +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanReaderGenerator.java @@ -46,4 +46,9 @@ protected Iterable getMapperMethods(Element element, TypeMirror bean protected void generateDeserializer(TypeMirror beanType) { new DeserializerGenerator().generate(beanType); } + + @Override + protected GeneratedMappersRegistry.Category getCategory() { + return GeneratedMappersRegistry.Category.READER; + } } diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanWriterGenerator.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanWriterGenerator.java index c1814380..fb8a5f0c 100644 --- a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanWriterGenerator.java +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/BeanWriterGenerator.java @@ -50,4 +50,9 @@ protected Iterable getMapperMethods(Element element, TypeMirror bean protected void generateSerializer(TypeMirror beanType) { new SerializerGenerator().generate(beanType); } + + @Override + protected GeneratedMappersRegistry.Category getCategory() { + return GeneratedMappersRegistry.Category.WRITER; + } } diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/DeserializerGenerator.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/DeserializerGenerator.java index 313f0f98..fd8db6a9 100644 --- a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/DeserializerGenerator.java +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/DeserializerGenerator.java @@ -45,7 +45,11 @@ public String generate(TypeMirror beanType) { MoreElements.getPackage(MoreTypes.asTypeElement(beanType)).getQualifiedName().toString(); String deserializerName = Type.deserializerName(packageName, beanType); - if (!TypeRegistry.containsDeserializer(Type.stringifyTypeWithPackage(beanType))) { + if (!GeneratedMappersRegistry.INSTANCE.hasTypeToken( + GeneratedMappersRegistry.Category.DESERIALIZER, beanType) + && !TypeRegistry.containsDeserializer(Type.stringifyTypeWithPackage(beanType))) { + GeneratedMappersRegistry.INSTANCE.addTypeToken( + GeneratedMappersRegistry.Category.DESERIALIZER, beanType); try { generateSubTypesDeserializers(beanType); TypeRegistry.addInActiveGenDeserializer(beanType); @@ -54,7 +58,8 @@ public String generate(TypeMirror beanType) { Type.stringifyTypeWithPackage(beanType), ClassName.bestGuess(deserializerName)); TypeRegistry.removeInActiveGenDeserializer(beanType); } catch (IOException e) { - throw new DeserializerGenerator.DeserializerGenerationFailedException(beanType.toString()); + throw new DeserializerGenerator.DeserializerGenerationFailedException( + beanType.toString(), e); } } return deserializerName; @@ -70,6 +75,10 @@ private void generateSubTypesDeserializers(TypeMirror beanType) { private class DeserializerGenerationFailedException extends RuntimeException { private static final long serialVersionUID = 1L; + public DeserializerGenerationFailedException(String message, Throwable cause) { + super(message, cause); + } + DeserializerGenerationFailedException(String type) { super(type); } diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/GeneratedMappersRegistry.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/GeneratedMappersRegistry.java new file mode 100644 index 00000000..a16b6eb6 --- /dev/null +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/GeneratedMappersRegistry.java @@ -0,0 +1,76 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.jackson.processor; + +import com.google.auto.common.MoreTypes; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import javax.lang.model.type.TypeMirror; + +public class GeneratedMappersRegistry { + + public static final GeneratedMappersRegistry INSTANCE = new GeneratedMappersRegistry(); + private final Map> typeTokens = new HashMap<>(); + + private GeneratedMappersRegistry() {} + + public void addTypeToken(Category category, TypeMirror typeMirror) { + if (!typeTokens.containsKey(category)) { + typeTokens.put(category, new HashSet<>()); + } + typeTokens.get(category).add(new GeneratedTypeToken(typeMirror)); + } + + public boolean hasTypeToken(Category category, TypeMirror typeMirror) { + if (typeTokens.containsKey(category)) { + return typeTokens.get(category).contains(new GeneratedTypeToken(typeMirror)); + } + return false; + + // return false; + } + + public enum Category { + MAPPER, + READER, + WRITER, + SERIALIZER, + DESERIALIZER + } + + public static class GeneratedTypeToken { + TypeMirror typeMirror; + + public GeneratedTypeToken(TypeMirror typeMirror) { + this.typeMirror = typeMirror; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GeneratedTypeToken that = (GeneratedTypeToken) o; + return MoreTypes.equivalence().equivalent(typeMirror, that.typeMirror); + } + + @Override + public int hashCode() { + return typeMirror.hashCode(); + } + } +} diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/ObjectMapperProcessor.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/ObjectMapperProcessor.java index e35f908f..aa67ddb4 100644 --- a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/ObjectMapperProcessor.java +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/ObjectMapperProcessor.java @@ -29,7 +29,7 @@ import org.dominokit.jackson.annotation.JSONWriter; /** - * ObjectMapperProcessor class. a Delegate class to geneate different types of mappers for all + * ObjectMapperProcessor class. a Delegate class to generate different types of mappers for all * annotated types. */ @AutoService(Processor.class) diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/SerializerGenerator.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/SerializerGenerator.java index 8641200a..132ea466 100644 --- a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/SerializerGenerator.java +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/SerializerGenerator.java @@ -41,7 +41,11 @@ public String generate(TypeMirror beanType) { String packageName = MoreElements.getPackage(MoreTypes.asTypeElement(beanType)).getQualifiedName().toString(); String serializerName = Type.serializerName(packageName, beanType); - if (!TypeRegistry.containsSerializer(Type.stringifyTypeWithPackage(beanType))) { + if (!GeneratedMappersRegistry.INSTANCE.hasTypeToken( + GeneratedMappersRegistry.Category.SERIALIZER, beanType) + && !TypeRegistry.containsSerializer(Type.stringifyTypeWithPackage(beanType))) { + GeneratedMappersRegistry.INSTANCE.addTypeToken( + GeneratedMappersRegistry.Category.SERIALIZER, beanType); try { generateSubTypeSerializers(beanType); TypeRegistry.addInActiveGenSerializer(beanType); diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/deserialization/DeserializerBuilder.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/deserialization/DeserializerBuilder.java index 22a061ed..3f2ace66 100644 --- a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/deserialization/DeserializerBuilder.java +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/deserialization/DeserializerBuilder.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.squareup.javapoet.*; +import java.beans.Introspector; import java.util.Optional; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; @@ -119,17 +120,15 @@ private MethodSpec buildParametersMethod() { } private AccessorInfo setterInfo(Element field) { - final String upperCaseFirstLetter = upperCaseFirstLetter(field.getSimpleName().toString()); - Optional accessor = getAccessors(beanType).stream() - .filter(accessorInfo -> accessorInfo.getName().equals("set" + upperCaseFirstLetter)) + .filter(accessorInfo -> accessorInfo.getName().startsWith("set")) + .filter( + accessorInfo -> + Introspector.decapitalize(accessorInfo.getName().substring(3)) + .equals(field.getSimpleName().toString())) .findFirst(); return accessor.orElseGet(() -> new AccessorInfo(field.getSimpleName().toString())); } - - private String upperCaseFirstLetter(String name) { - return name.substring(0, 1).toUpperCase() + name.substring(1); - } } diff --git a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/serialization/SerializerBuilder.java b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/serialization/SerializerBuilder.java index 211100b5..d824161e 100644 --- a/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/serialization/SerializerBuilder.java +++ b/domino-jackson-processor/src/main/java/org/dominokit/jackson/processor/serialization/SerializerBuilder.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import com.squareup.javapoet.*; +import java.beans.Introspector; import java.util.Optional; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; @@ -160,17 +161,19 @@ private boolean hasTypeJsonInclude() { } AbstractJsonMapperGenerator.AccessorInfo getterInfo() { - final String upperCaseFirstLetter = upperCaseFirstLetter(field.getSimpleName().toString()); String prefix = field.asType().getKind() == TypeKind.BOOLEAN ? "is" : "get"; Optional accessor = getAccessors(beanType).stream() - .filter(accessorInfo -> accessorInfo.getName().equals(prefix + upperCaseFirstLetter)) + .filter( + accessorInfo -> + accessorInfo.getName().startsWith("is") + || accessorInfo.getName().startsWith("get")) + .filter( + accessorInfo -> + Introspector.decapitalize(accessorInfo.getName().substring(prefix.length())) + .equals(field.getSimpleName().toString())) .findFirst(); return accessor.orElseGet( () -> new AbstractJsonMapperGenerator.AccessorInfo(field.getSimpleName().toString())); } - - private String upperCaseFirstLetter(String name) { - return name.substring(0, 1).toUpperCase() + name.substring(1); - } } diff --git a/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/AccessorBean.java b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/AccessorBean.java new file mode 100644 index 00000000..fe2fcc0c --- /dev/null +++ b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/AccessorBean.java @@ -0,0 +1,36 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.jackson.processor; + +import org.dominokit.jackson.annotation.JSONMapper; + +/** + * To make sure some wierd accessors case works + * + * @see https://github.com/DominoKit/domino-jackson/issues/66 + */ +@JSONMapper +public class AccessorBean { + private int xY; + + public int getxY() { + return xY; + } + + public void setxY(int xY) { + this.xY = xY; + } +} diff --git a/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/A.java b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/A.java new file mode 100644 index 00000000..d21085f4 --- /dev/null +++ b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/A.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.jackson.processor.recursive; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import org.dominokit.jackson.annotation.JSONMapper; + +@JSONMapper +@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, visible = true) +@JsonSubTypes({ + @Type(value = D.class, name = "dominokit.recursive.D"), + @Type(value = E.class, name = "dominokit.recursive.E"), + @Type(value = F.class, name = "dominokit.recursive.F") +}) +public interface A {} diff --git a/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/B.java b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/B.java new file mode 100644 index 00000000..98cd53d9 --- /dev/null +++ b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/B.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.jackson.processor.recursive; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; + +@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, visible = true) +@JsonSubTypes({ + @Type(value = D.class, name = "dominokit.recursive.D"), + @Type(value = E.class, name = "dominokit.recursive.E") +}) +public interface B extends A {} diff --git a/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/C.java b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/C.java new file mode 100644 index 00000000..dcb0531a --- /dev/null +++ b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/C.java @@ -0,0 +1,18 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.jackson.processor.recursive; + +public interface C extends B {} diff --git a/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/D.java b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/D.java new file mode 100644 index 00000000..e518cfcb --- /dev/null +++ b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/D.java @@ -0,0 +1,21 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.jackson.processor.recursive; + +public class D implements B { + + public D() {} +} diff --git a/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/E.java b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/E.java new file mode 100644 index 00000000..6b59c461 --- /dev/null +++ b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/E.java @@ -0,0 +1,27 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.jackson.processor.recursive; + +public class E implements C { + + public B b; + + public E() {} + + public E(B b) { + this.b = b; + } +} diff --git a/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/F.java b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/F.java new file mode 100644 index 00000000..cd7aa7a7 --- /dev/null +++ b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/F.java @@ -0,0 +1,18 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.jackson.processor.recursive; + +public class F implements A {} diff --git a/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/RecursiveMapperTest.java b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/RecursiveMapperTest.java new file mode 100644 index 00000000..def2a455 --- /dev/null +++ b/domino-jackson-processor/src/test/java/org/dominokit/jackson/processor/recursive/RecursiveMapperTest.java @@ -0,0 +1,27 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.jackson.processor.recursive; + +import org.junit.Test; + +public class RecursiveMapperTest { + + @Test + public void recursiveMappersShouldBeCreatedWithoutErrors() { + A_MapperImpl.INSTANCE.read("{\"@type\":\"dominokit.recursive.F\"}"); + A_MapperImpl.INSTANCE.write(new F()); + } +} diff --git a/domino-jackson-super/pom.xml b/domino-jackson-super/pom.xml index 6e7b0ca3..3e3c6997 100644 --- a/domino-jackson-super/pom.xml +++ b/domino-jackson-super/pom.xml @@ -6,7 +6,7 @@ org.dominokit domino-jackson-parent - 1.0.0 + 1.0.1 domino-jackson-super diff --git a/domino-jackson/pom.xml b/domino-jackson/pom.xml index 9d00f47e..fe0abdc8 100644 --- a/domino-jackson/pom.xml +++ b/domino-jackson/pom.xml @@ -6,7 +6,7 @@ org.dominokit domino-jackson-parent - 1.0.0 + 1.0.1 domino-jackson diff --git a/domino-jackson/src/main/java/org/dominokit/jackson/registration/TypeToken.java b/domino-jackson/src/main/java/org/dominokit/jackson/registration/TypeToken.java index 4ec48eb5..e1c849d9 100644 --- a/domino-jackson/src/main/java/org/dominokit/jackson/registration/TypeToken.java +++ b/domino-jackson/src/main/java/org/dominokit/jackson/registration/TypeToken.java @@ -67,7 +67,7 @@ public class TypeToken implements Comparable> { private TypeToken[] typeArguments; public static TypeToken of(Class type) { - return new TypeToken(type, new TypeToken[0]); + return new TypeToken<>(type); } protected TypeToken(Class rawType, TypeToken... typeArguments) { @@ -77,7 +77,7 @@ protected TypeToken(Class rawType, TypeToken... typeArguments) { // and the array component type is in the type arguments if (typeArguments.length > 0) throw new IllegalArgumentException( - "To create a type token for an array, either pass the non-generic array class instance as the raw type and keep the type argumetns empty, or pass null as raw type and provide a single type argument for the component type of the (possibly generic) array"); + "To create a type token for an array, either pass the non-generic array class instance as the raw type and keep the type arguments empty, or pass null as raw type and provide a single type argument for the component type of the (possibly generic) array"); typeArguments = new TypeToken[] {TypeToken.of(rawType.getComponentType())}; rawType = null; diff --git a/domino-jackson/src/main/java/org/dominokit/jackson/stream/impl/DefaultJsonWriter.java b/domino-jackson/src/main/java/org/dominokit/jackson/stream/impl/DefaultJsonWriter.java index ffea3a8c..68dc5387 100644 --- a/domino-jackson/src/main/java/org/dominokit/jackson/stream/impl/DefaultJsonWriter.java +++ b/domino-jackson/src/main/java/org/dominokit/jackson/stream/impl/DefaultJsonWriter.java @@ -433,12 +433,17 @@ public DefaultJsonWriter value(boolean value) { /** {@inheritDoc} */ @Override public DefaultJsonWriter value(double value) { - if (Double.isNaN(value) || Double.isInfinite(value)) { + final boolean isNaNorInfinity = Double.isNaN(value) || Double.isInfinite(value); + if (!lenient && isNaNorInfinity) { throw new IllegalArgumentException("Numeric values must be finite, but was " + value); } writeDeferredName(); beforeValue(false); - out.append(value); + if (isNaNorInfinity) { + string(Double.toString(value)); + } else { + out.append(value); + } return this; } diff --git a/domino-jackson/src/main/java/org/dominokit/jackson/stream/impl/FastJsonWriter.java b/domino-jackson/src/main/java/org/dominokit/jackson/stream/impl/FastJsonWriter.java index 5e6e5fff..1950b9ec 100644 --- a/domino-jackson/src/main/java/org/dominokit/jackson/stream/impl/FastJsonWriter.java +++ b/domino-jackson/src/main/java/org/dominokit/jackson/stream/impl/FastJsonWriter.java @@ -301,12 +301,17 @@ public FastJsonWriter value(boolean value) { /** {@inheritDoc} */ @Override public FastJsonWriter value(double value) { - if (Double.isNaN(value) || Double.isInfinite(value)) { + final boolean isNaNorInfinity = Double.isNaN(value) || Double.isInfinite(value); + if (!lenient && isNaNorInfinity) { throw new IllegalArgumentException("Numeric values must be finite, but was " + value); } writeDeferredName(); beforeValue(false); - out.append(value); + if (isNaNorInfinity) { + string(Double.toString(value)); + } else { + out.append(value); + } return this; } diff --git a/domino-jackson/src/test/java/org/dominokit/jackson/client/deser/number/DoubleJsonDeserializerTest.java b/domino-jackson/src/test/java/org/dominokit/jackson/client/deser/number/DoubleJsonDeserializerTest.java index cbc54ab6..a6e3bcc6 100644 --- a/domino-jackson/src/test/java/org/dominokit/jackson/client/deser/number/DoubleJsonDeserializerTest.java +++ b/domino-jackson/src/test/java/org/dominokit/jackson/client/deser/number/DoubleJsonDeserializerTest.java @@ -34,5 +34,7 @@ public void testDeserializeValue() { assertDeserialization(-784.15454d, "\"-784.15454\""); assertDeserialization(Double.MIN_VALUE, "4.9E-324"); assertDeserialization(Double.MAX_VALUE, "1.7976931348623157e+308"); + assertTrue(Double.isNaN(deserialize("\"NaN\""))); + assertDeserialization(Double.NEGATIVE_INFINITY, "\"-Infinity\""); } } diff --git a/domino-jackson/src/test/java/org/dominokit/jackson/client/ser/number/DoubleJsonSerializerTest.java b/domino-jackson/src/test/java/org/dominokit/jackson/client/ser/number/DoubleJsonSerializerTest.java index d559ebbd..45ea9b50 100644 --- a/domino-jackson/src/test/java/org/dominokit/jackson/client/ser/number/DoubleJsonSerializerTest.java +++ b/domino-jackson/src/test/java/org/dominokit/jackson/client/ser/number/DoubleJsonSerializerTest.java @@ -38,5 +38,7 @@ public void testSerializeValue() { ? "1.7976931348623157e+308" : "1.7976931348623157E308"), Double.MAX_VALUE); + assertSerialization("\"NaN\"", Double.NaN); + assertSerialization("\"-Infinity\"", Double.NEGATIVE_INFINITY); } } diff --git a/domino-jackson/src/test/java/org/dominokit/jackson/server/deser/number/DoubleJsonDeserializerTest.java b/domino-jackson/src/test/java/org/dominokit/jackson/server/deser/number/DoubleJsonDeserializerTest.java index 869d25a7..6ad992e0 100644 --- a/domino-jackson/src/test/java/org/dominokit/jackson/server/deser/number/DoubleJsonDeserializerTest.java +++ b/domino-jackson/src/test/java/org/dominokit/jackson/server/deser/number/DoubleJsonDeserializerTest.java @@ -16,6 +16,8 @@ package org.dominokit.jackson.server.deser.number; +import static org.junit.Assert.assertTrue; + import org.dominokit.jackson.deser.BaseNumberJsonDeserializer.DoubleJsonDeserializer; import org.dominokit.jackson.server.deser.AbstractJsonDeserializerTest; import org.junit.Test; @@ -36,5 +38,7 @@ public void testDeserializeValue() { assertDeserialization(-784.15454d, "\"-784.15454\""); assertDeserialization(Double.MIN_VALUE, "4.9E-324"); assertDeserialization(Double.MAX_VALUE, "1.7976931348623157e+308"); + assertTrue(Double.isNaN(deserialize("\"NaN\""))); + assertDeserialization(Double.NEGATIVE_INFINITY, "-Infinity"); } } diff --git a/domino-jackson/src/test/java/org/dominokit/jackson/server/ser/number/DoubleJsonSerializerTest.java b/domino-jackson/src/test/java/org/dominokit/jackson/server/ser/number/DoubleJsonSerializerTest.java index 2567a93c..ab733469 100644 --- a/domino-jackson/src/test/java/org/dominokit/jackson/server/ser/number/DoubleJsonSerializerTest.java +++ b/domino-jackson/src/test/java/org/dominokit/jackson/server/ser/number/DoubleJsonSerializerTest.java @@ -34,5 +34,7 @@ public void testSerializeValue() { assertSerialization("-784.15454", -784.15454d); assertSerialization("4.9E-324", Double.MIN_VALUE); assertSerialization("1.7976931348623157E308", Double.MAX_VALUE); + assertSerialization("\"NaN\"", Double.NaN); + assertSerialization("\"-Infinity\"", Double.NEGATIVE_INFINITY); } } diff --git a/pom.xml b/pom.xml index cc01dfba..48bafe2a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.dominokit domino-jackson-parent - 1.0.0 + 1.0.1 pom domino-jackson-parent @@ -67,7 +67,7 @@ HEAD-SNAPSHOT - 1.0.0 + 1.0.1 1.8 1.8 UTF-8