Skip to content

Commit

Permalink
fix #70 Compilation error in case of recursive class structures
Browse files Browse the repository at this point in the history
  • Loading branch information
vegegoku committed Nov 5, 2023
1 parent a5b2285 commit b273252
Show file tree
Hide file tree
Showing 18 changed files with 306 additions and 30 deletions.
1 change: 0 additions & 1 deletion .mvn/maven.config

This file was deleted.

6 changes: 0 additions & 6 deletions .mvn/settings.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,9 @@ protected Iterable<MethodSpec> getMapperMethods(Element element, TypeMirror bean
protected void generateDeserializer(TypeMirror beanType) {
new DeserializerGenerator().generate(beanType);
}

@Override
protected GeneratedMappersRegistry.Category getCategory() {
return GeneratedMappersRegistry.Category.READER;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,9 @@ protected Iterable<MethodSpec> getMapperMethods(Element element, TypeMirror bean
protected void generateSerializer(TypeMirror beanType) {
new SerializerGenerator().generate(beanType);
}

@Override
protected GeneratedMappersRegistry.Category getCategory() {
return GeneratedMappersRegistry.Category.WRITER;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Category, Set<GeneratedTypeToken>> 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();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {}
Original file line number Diff line number Diff line change
@@ -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 {}
Original file line number Diff line number Diff line change
@@ -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 {}
Original file line number Diff line number Diff line change
@@ -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() {}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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 {}
Loading

0 comments on commit b273252

Please sign in to comment.