From 96b2669a00dc1396138f863bbc11aa0b0aa3f0b6 Mon Sep 17 00:00:00 2001 From: Michal Hajas Date: Mon, 20 Dec 2021 16:04:56 +0100 Subject: [PATCH] Refactoring of constructors for generated entities --- ...enerateEntityImplementationsProcessor.java | 5 +- .../map/processor/FieldAccessorType.java | 9 ++-- ...enerateEntityImplementationsProcessor.java | 43 ++++++++--------- ...eHotRodEntityImplementationsProcessor.java | 47 +++++++++---------- .../keycloak/models/map/processor/Util.java | 7 +++ .../HotRodMapStorageProviderFactory.java | 4 +- .../jpa/client/entity/JpaClientEntity.java | 6 +++ .../jpa/client/entity/JpaClientMetadata.java | 9 ++++ .../models/map/common/DeepCloner.java | 40 +++------------- ...ncurrentHashMapStorageProviderFactory.java | 8 ++-- .../map/client/MapClientEntityClonerTest.java | 2 +- 11 files changed, 89 insertions(+), 91 deletions(-) diff --git a/model/build-processor/src/main/java/org/keycloak/models/map/processor/AbstractGenerateEntityImplementationsProcessor.java b/model/build-processor/src/main/java/org/keycloak/models/map/processor/AbstractGenerateEntityImplementationsProcessor.java index b2c3563055..0cb7778fce 100644 --- a/model/build-processor/src/main/java/org/keycloak/models/map/processor/AbstractGenerateEntityImplementationsProcessor.java +++ b/model/build-processor/src/main/java/org/keycloak/models/map/processor/AbstractGenerateEntityImplementationsProcessor.java @@ -50,6 +50,7 @@ import javax.lang.model.SourceVersion; import static org.keycloak.models.map.processor.FieldAccessorType.GETTER; import static org.keycloak.models.map.processor.Util.getGenericsDeclaration; import static org.keycloak.models.map.processor.Util.isMapType; +import static org.keycloak.models.map.processor.Util.singularToPlural; @SupportedSourceVersion(SourceVersion.RELEASE_8) public abstract class AbstractGenerateEntityImplementationsProcessor extends AbstractProcessor { @@ -123,11 +124,11 @@ public abstract class AbstractGenerateEntityImplementationsProcessor extends Abs // Merge plurals with singulars methodsPerAttribute.keySet().stream() - .filter(key -> methodsPerAttribute.containsKey(key + "s")) + .filter(key -> methodsPerAttribute.containsKey(singularToPlural(key))) .collect(Collectors.toSet()) .forEach(key -> { HashSet removed = methodsPerAttribute.remove(key); - methodsPerAttribute.get(key + "s").addAll(removed); + methodsPerAttribute.get(singularToPlural(key)).addAll(removed); }); return methodsPerAttribute; diff --git a/model/build-processor/src/main/java/org/keycloak/models/map/processor/FieldAccessorType.java b/model/build-processor/src/main/java/org/keycloak/models/map/processor/FieldAccessorType.java index 90389d73ea..fcd4070a56 100644 --- a/model/build-processor/src/main/java/org/keycloak/models/map/processor/FieldAccessorType.java +++ b/model/build-processor/src/main/java/org/keycloak/models/map/processor/FieldAccessorType.java @@ -26,6 +26,7 @@ import javax.lang.model.element.Name; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Types; import static org.keycloak.models.map.processor.Util.getGenericsDeclaration; +import static org.keycloak.models.map.processor.Util.pluralToSingular; /** * @@ -52,7 +53,7 @@ enum FieldAccessorType { COLLECTION_ADD { @Override public boolean is(ExecutableElement method, String fieldName, Types types, TypeMirror fieldType) { - String fieldNameSingular = fieldName.endsWith("s") ? fieldName.substring(0, fieldName.length() - 1) : fieldName; + String fieldNameSingular = pluralToSingular(fieldName); String methodName = "add" + fieldNameSingular; List res = getGenericsDeclaration(fieldType); return Objects.equals(methodName, method.getSimpleName().toString()) @@ -63,7 +64,7 @@ enum FieldAccessorType { COLLECTION_DELETE { @Override public boolean is(ExecutableElement method, String fieldName, Types types, TypeMirror fieldType) { - String fieldNameSingular = fieldName.endsWith("s") ? fieldName.substring(0, fieldName.length() - 1) : fieldName; + String fieldNameSingular = pluralToSingular(fieldName); String removeFromCollection = "remove" + fieldNameSingular; List res = getGenericsDeclaration(fieldType); return Objects.equals(removeFromCollection, method.getSimpleName().toString()) @@ -74,7 +75,7 @@ enum FieldAccessorType { MAP_ADD { @Override public boolean is(ExecutableElement method, String fieldName, Types types, TypeMirror fieldType) { - String fieldNameSingular = fieldName.endsWith("s") ? fieldName.substring(0, fieldName.length() - 1) : fieldName; + String fieldNameSingular = pluralToSingular(fieldName); String methodName = "set" + fieldNameSingular; List res = getGenericsDeclaration(fieldType); return Objects.equals(methodName, method.getSimpleName().toString()) @@ -86,7 +87,7 @@ enum FieldAccessorType { MAP_GET { @Override public boolean is(ExecutableElement method, String fieldName, Types types, TypeMirror fieldType) { - String fieldNameSingular = fieldName.endsWith("s") ? fieldName.substring(0, fieldName.length() - 1) : fieldName; + String fieldNameSingular = pluralToSingular(fieldName); String methodName = "get" + fieldNameSingular; List res = getGenericsDeclaration(fieldType); return Objects.equals(methodName, method.getSimpleName().toString()) diff --git a/model/build-processor/src/main/java/org/keycloak/models/map/processor/GenerateEntityImplementationsProcessor.java b/model/build-processor/src/main/java/org/keycloak/models/map/processor/GenerateEntityImplementationsProcessor.java index 3c82a773e5..88aca7efa0 100644 --- a/model/build-processor/src/main/java/org/keycloak/models/map/processor/GenerateEntityImplementationsProcessor.java +++ b/model/build-processor/src/main/java/org/keycloak/models/map/processor/GenerateEntityImplementationsProcessor.java @@ -171,7 +171,7 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti pw.println(" return " + types.erasure(firstParameterType) + ".class;"); pw.println(" }"); }); - + FieldAccessorType.getMethod(FieldAccessorType.MAP_ADD, methods, fieldName, types, fieldType).ifPresent(method -> { TypeMirror firstParameterType = method.getParameters().get(0).asType(); TypeMirror secondParameterType = method.getParameters().get(1).asType(); @@ -182,7 +182,7 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti pw.println(" return " + types.erasure(secondParameterType) + ".class;"); pw.println(" }"); }); - + for (ExecutableElement ee : methods) { FieldAccessorType fat = FieldAccessorType.determineType(ee, fieldName, types, fieldType); printMethodBody(pw, fat, ee, className, fieldType); @@ -265,6 +265,7 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti boolean needsDeepClone = fieldGetters(methodsPerAttribute) .map(ExecutableElement::getReturnType) .anyMatch(fieldType -> ! isKnownCollectionOfImmutableFinalTypes(fieldType) && ! isImmutableFinalType(fieldType)); + boolean usingGeneratedCloner = ! hasDeepClone && needsDeepClone; JavaFileObject file = processingEnv.getFiler().createSourceFile(mapImplClassName); try (PrintWriter pw = new PrintWriterNoJavaLang(file.openWriter())) { @@ -283,28 +284,26 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti .map(ExecutableElement.class::cast) .filter((ExecutableElement ee) -> ee.getKind() == ElementKind.CONSTRUCTOR) .forEach((ExecutableElement ee) -> { - if (hasDeepClone || ! needsDeepClone) { - pw.println(" " - + ee.getModifiers().stream().map(Object::toString).collect(Collectors.joining(" ")) - + " " + mapSimpleClassName + "(" + methodParameters(ee.getParameters()) + ") { super(" + ee.getParameters() + "); }" - ); - } else if (needsDeepClone) { + // Create constructor and initialize cloner to DUMB_CLONER if necessary + if (usingGeneratedCloner) { pw.println(" /**"); pw.println(" * @deprecated This constructor uses a {@link DeepCloner#DUMB_CLONER} that does not clone anything. Use {@link #" + mapSimpleClassName + "(DeepCloner)} variant instead"); pw.println(" */"); - pw.println(" " - + ee.getModifiers().stream().map(Object::toString).collect(Collectors.joining(" ")) - + " " - + mapSimpleClassName + "(" + methodParameters(ee.getParameters()) + ") { this(DeepCloner.DUMB_CLONER" + (ee.getParameters().isEmpty() ? "" : ", ") + ee.getParameters() + "); }" - ); - pw.println(" " - + ee.getModifiers().stream().map(Object::toString).collect(Collectors.joining(" ")) - + " " - + mapSimpleClassName + "(DeepCloner cloner" + (ee.getParameters().isEmpty() ? "" : ", ") + methodParameters(ee.getParameters()) + ") { super(" + ee.getParameters() + "); this.cloner = cloner; }" - ); } + pw.println(" " + + ee.getModifiers().stream().map(Object::toString).collect(Collectors.joining(" ")) + + " " + mapSimpleClassName + "(" + methodParameters(ee.getParameters()) + ") {" + ); + pw.println(" super(" + ee.getParameters() + ");"); + if (usingGeneratedCloner) pw.println(" this.cloner = DeepCloner.DUMB_CLONER;"); + pw.println(" }"); }); + pw.println(" " + + "public " + + mapSimpleClassName + "(DeepCloner cloner) { super(); " + (!usingGeneratedCloner ? "" : "this.cloner = cloner;") + "}" + ); + // equals, hashCode, toString pw.println(" @Override public boolean equals(Object o) {"); pw.println(" if (o == this) return true; "); @@ -339,7 +338,7 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti pw.println(" }"); // deepClone - if (! hasDeepClone && needsDeepClone) { + if (usingGeneratedCloner) { pw.println(" private final DeepCloner cloner;"); pw.println(" public V deepClone(V obj) {"); pw.println(" return cloner.from(obj);"); @@ -363,7 +362,7 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti if (parentMethod.isPresent()) { processingEnv.getMessager().printMessage(Kind.OTHER, "Method " + method + " is declared in a parent class.", method); - } else if (fat != FieldAccessorType.UNKNOWN && ! printMethodBody(pw, fat, method, "f" + me.getKey(), fieldType)) { + } else if (fat == FieldAccessorType.UNKNOWN || ! printMethodBody(pw, fat, method, "f" + me.getKey(), fieldType)) { processingEnv.getMessager().printMessage(Kind.WARNING, "Could not determine desired semantics of method from its signature", method); } } @@ -446,10 +445,12 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti pw.println(" }"); return true; case COLLECTION_DELETE: + boolean needsReturn = method.getReturnType().getKind() != TypeKind.VOID; pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0) {"); - pw.println(" if (" + fieldName + " == null) { return; }"); + pw.println(" if (" + fieldName + " == null) { return" + (needsReturn ? " false" : "") + "; }"); pw.println(" boolean removed = " + fieldName + ".remove(p0)" + ("java.util.Map".equals(typeElement.getQualifiedName().toString()) ? " != null" : "") + ";"); pw.println(" updated |= removed;"); + if (needsReturn) pw.println(" return removed;"); pw.println(" }"); return true; case MAP_ADD: diff --git a/model/build-processor/src/main/java/org/keycloak/models/map/processor/GenerateHotRodEntityImplementationsProcessor.java b/model/build-processor/src/main/java/org/keycloak/models/map/processor/GenerateHotRodEntityImplementationsProcessor.java index f9a2fdead7..2ebb8e3abb 100644 --- a/model/build-processor/src/main/java/org/keycloak/models/map/processor/GenerateHotRodEntityImplementationsProcessor.java +++ b/model/build-processor/src/main/java/org/keycloak/models/map/processor/GenerateHotRodEntityImplementationsProcessor.java @@ -104,6 +104,7 @@ public class GenerateHotRodEntityImplementationsProcessor extends AbstractGenera boolean needsDeepClone = fieldGetters(methodsPerAttribute) .map(ExecutableElement::getReturnType) .anyMatch(fieldType -> ! isKnownCollectionOfImmutableFinalTypes(fieldType) && ! isImmutableFinalType(fieldType)); + boolean usingGeneratedCloner = ! hasDeepClone && needsDeepClone; boolean hasId = methodsPerAttribute.containsKey("Id") || allMembers.stream().anyMatch(el -> "getId".equals(el.getSimpleName().toString())); JavaFileObject file = processingEnv.getFiler().createSourceFile(hotRodImplClassName); @@ -132,45 +133,43 @@ public class GenerateHotRodEntityImplementationsProcessor extends AbstractGenera .map(ExecutableElement.class::cast) .filter((ExecutableElement ee) -> ee.getKind() == ElementKind.CONSTRUCTOR) .forEach((ExecutableElement ee) -> { - if (hasDeepClone || ! needsDeepClone) { - pw.println(" " - + ee.getModifiers().stream().map(Object::toString).collect(Collectors.joining(" ")) - + " " + hotRodSimpleClassName + "(" + methodParameters(ee.getParameters()) + ") {" - ); - pw.println(" super(" + ee.getParameters() + ");"); - pw.println(" this." + ENTITY_VARIABLE + " = new " + className + "();"); - pw.println(" }"); - } else if (needsDeepClone) { + // Create constructor and initialize cloner to DUMB_CLONER if necessary + if (usingGeneratedCloner) { pw.println(" /**"); pw.println(" * @deprecated This constructor uses a {@link DeepCloner#DUMB_CLONER} that does not clone anything. Use {@link #" + hotRodSimpleClassName + "(DeepCloner)} variant instead"); pw.println(" */"); - pw.println(" " - + ee.getModifiers().stream().map(Object::toString).collect(Collectors.joining(" ")) - + " " - + hotRodSimpleClassName + "(" + methodParameters(ee.getParameters()) + ") { this(DeepCloner.DUMB_CLONER" + (ee.getParameters().isEmpty() ? "" : ", ") + ee.getParameters() + "); }" - ); - pw.println(" " - + ee.getModifiers().stream().map(Object::toString).collect(Collectors.joining(" ")) - + " " - + hotRodSimpleClassName + "(DeepCloner cloner" + (ee.getParameters().isEmpty() ? "" : ", ") + methodParameters(ee.getParameters()) + ") {" - ); - pw.println(" super(" + ee.getParameters() + ");"); - pw.println(" this.cloner = cloner;"); - pw.println(" this." + ENTITY_VARIABLE + " = new " + className + "();"); - pw.println(" }"); } + pw.println(" " + + ee.getModifiers().stream().map(Object::toString).collect(Collectors.joining(" ")) + + " " + hotRodSimpleClassName + "(" + methodParameters(ee.getParameters()) + ") {" + ); + pw.println(" super(" + ee.getParameters() + ");"); + if (usingGeneratedCloner) pw.println(" this.cloner = DeepCloner.DUMB_CLONER;"); + pw.println(" this." + ENTITY_VARIABLE + " = new " + className + "();"); + pw.println(" }"); }); // Add constructor for setting HotRodEntity + if (usingGeneratedCloner) { + pw.println(" /**"); + pw.println(" * @deprecated This constructor uses a {@link DeepCloner#DUMB_CLONER} that does not clone anything. Use {@link #" + hotRodSimpleClassName + "(DeepCloner)} variant instead"); + pw.println(" */"); + } pw.println(" " + "public " + hotRodSimpleClassName + "(" + className + " " + ENTITY_VARIABLE + ") {" ); pw.println(" this." + ENTITY_VARIABLE + " = " + ENTITY_VARIABLE + ";"); - if (! hasDeepClone && needsDeepClone) { + if (usingGeneratedCloner) { pw.println(" this.cloner = DeepCloner.DUMB_CLONER;"); } pw.println(" }"); + pw.println(" public " + hotRodSimpleClassName + "(DeepCloner cloner) {"); + pw.println(" super();"); + pw.println(" this." + ENTITY_VARIABLE + " = new " + className + "();"); + if (usingGeneratedCloner) pw.println(" this.cloner = cloner;"); + pw.println(" }"); + // equals, hashCode, toString pw.println(" @Override public boolean equals(Object o) {"); pw.println(" if (o == this) return true; "); diff --git a/model/build-processor/src/main/java/org/keycloak/models/map/processor/Util.java b/model/build-processor/src/main/java/org/keycloak/models/map/processor/Util.java index d7090c091f..ade5a0bfed 100644 --- a/model/build-processor/src/main/java/org/keycloak/models/map/processor/Util.java +++ b/model/build-processor/src/main/java/org/keycloak/models/map/processor/Util.java @@ -99,4 +99,11 @@ public class Util { .findAny(); } + public static String singularToPlural(String word) { + return word.endsWith("y") ? word.substring(0, word.length() -1) + "ies" : word + "s"; + } + + public static String pluralToSingular(String word) { + return word.endsWith("ies") ? word.substring(0, word.length() - 3) + "y" : word.endsWith("s") ? word.substring(0, word.length() - 1) : word; + } } diff --git a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/HotRodMapStorageProviderFactory.java b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/HotRodMapStorageProviderFactory.java index 69d10776c9..e65c632e4d 100644 --- a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/HotRodMapStorageProviderFactory.java +++ b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/HotRodMapStorageProviderFactory.java @@ -49,9 +49,9 @@ public class HotRodMapStorageProviderFactory implements AmphibianProviderFactory private static final Logger LOG = Logger.getLogger(HotRodMapStorageProviderFactory.class); private final static DeepCloner CLONER = new DeepCloner.Builder() - .constructorDC(MapClientEntity.class, HotRodClientEntityDelegate::new) + .constructor(MapClientEntity.class, HotRodClientEntityDelegate::new) .constructor(MapProtocolMapperEntity.class, HotRodProtocolMapperEntityDelegate::new) - .constructorDC(MapGroupEntity.class, HotRodGroupEntityDelegate::new) + .constructor(MapGroupEntity.class, HotRodGroupEntityDelegate::new) .build(); public static final Map, HotRodEntityDescriptor> ENTITY_DESCRIPTOR_MAP = new HashMap<>(); diff --git a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/client/entity/JpaClientEntity.java b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/client/entity/JpaClientEntity.java index 40cb8cccc4..957d963082 100644 --- a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/client/entity/JpaClientEntity.java +++ b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/client/entity/JpaClientEntity.java @@ -42,6 +42,8 @@ import org.hibernate.annotations.TypeDefs; import org.keycloak.models.map.client.MapClientEntity.AbstractClientEntity; import org.keycloak.models.map.client.MapProtocolMapperEntity; import static org.keycloak.models.map.storage.jpa.client.JpaClientMapStorage.SUPPORTED_VERSION; + +import org.keycloak.models.map.common.DeepCloner; import org.keycloak.models.map.storage.jpa.hibernate.jsonb.JsonbType; @Entity @@ -87,6 +89,10 @@ public class JpaClientEntity extends AbstractClientEntity implements Serializabl this.metadata = new JpaClientMetadata(); } + public JpaClientEntity(DeepCloner cloner) { + this.metadata = new JpaClientMetadata(cloner); + } + /** * Used by hibernate when calling cb.construct from read(QueryParameters) method. * It is used to select client without metadata(json) field. diff --git a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/client/entity/JpaClientMetadata.java b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/client/entity/JpaClientMetadata.java index e4c6492c59..e5d47e832a 100644 --- a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/client/entity/JpaClientMetadata.java +++ b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/client/entity/JpaClientMetadata.java @@ -18,9 +18,18 @@ package org.keycloak.models.map.storage.jpa.client.entity; import java.io.Serializable; import org.keycloak.models.map.client.MapClientEntityImpl; +import org.keycloak.models.map.common.DeepCloner; public class JpaClientMetadata extends MapClientEntityImpl implements Serializable { + public JpaClientMetadata(DeepCloner cloner) { + super(cloner); + } + + public JpaClientMetadata() { + super(); + } + private Integer entityVersion; public Integer getEntityVersion() { diff --git a/model/map/src/main/java/org/keycloak/models/map/common/DeepCloner.java b/model/map/src/main/java/org/keycloak/models/map/common/DeepCloner.java index fd6bcf3745..6560f3e137 100644 --- a/model/map/src/main/java/org/keycloak/models/map/common/DeepCloner.java +++ b/model/map/src/main/java/org/keycloak/models/map/common/DeepCloner.java @@ -111,7 +111,6 @@ public class DeepCloner { * Builder for the {@code DeepCloner} helper class. */ public static class Builder { - private final Map, Supplier> parameterlessConstructors = new HashMap<>(); private final Map, Function> constructors = new HashMap<>(); private final Map, Cloner> clonersWithId = new HashMap<>(org.keycloak.models.map.common.AutogeneratedCloners.CLONERS_WITH_ID); private final Map, Cloner> clonersWithoutId = new HashMap<>(org.keycloak.models.map.common.AutogeneratedCloners.CLONERS_WITHOUT_ID); @@ -124,7 +123,7 @@ public class DeepCloner { * @return */ public DeepCloner build() { - return new DeepCloner(parameterlessConstructors, constructors, delegateCreators, entityFieldDelegateCreators, clonersWithId, clonersWithoutId, genericCloner); + return new DeepCloner(constructors, delegateCreators, entityFieldDelegateCreators, clonersWithId, clonersWithoutId, genericCloner); } private void forThisClassAndAllMarkedParentsAndInterfaces(Class rootClazz, Consumer> action) { @@ -149,22 +148,6 @@ public class DeepCloner { } } - /** - * Adds a method, often a constructor, that instantiates a record of type {@code V}. - * - * @param Class or interface that would be instantiated by the given methods - * @param clazz Class or interface that would be instantiated by the given methods - * @param constructorNoParameters Parameterless function that creates a new instance of class {@code V}. - * If {@code null}, parameterless constructor is not available. - * @return This builder. - */ - public Builder constructor(Class clazz, Supplier constructorNoParameters) { - if (constructorNoParameters != null) { - forThisClassAndAllMarkedParentsAndInterfaces(clazz, cl -> this.parameterlessConstructors.put(cl, constructorNoParameters)); - } - return this; - } - /** * Adds a method, often a constructor, that instantiates a record of type {@code V}. * @@ -174,7 +157,7 @@ public class DeepCloner { * If {@code null}, such a single-parameter constructor is not available. * @return This builder. */ - public Builder constructorDC(Class clazz, Function constructor) { + public Builder constructor(Class clazz, Function constructor) { if (constructor != null) { forThisClassAndAllMarkedParentsAndInterfaces(clazz, cl -> this.constructors.put(cl, constructor)); } @@ -267,7 +250,6 @@ public class DeepCloner { private static final Logger LOG = Logger.getLogger(DeepCloner.class); - private final Map, Supplier> parameterlessConstructors; private final Map, Function> constructors; private final Map, Cloner> clonersWithId; private final Map, Cloner> clonersWithoutId; @@ -276,14 +258,12 @@ public class DeepCloner { private final Cloner genericCloner; private final Map, Object> emptyInstances = new HashMap<>(AutogeneratedCloners.EMPTY_INSTANCES); - private DeepCloner(Map, Supplier> parameterlessConstructors, - Map, Function> constructors, + private DeepCloner(Map, Function> constructors, Map, DelegateCreator> delegateCreators, Map, EntityFieldDelegateCreator> entityFieldDelegateCreators, Map, Cloner> clonersWithId, Map, Cloner> clonersWithoutId, Cloner genericCloner) { - this.parameterlessConstructors = parameterlessConstructors; this.constructors = constructors; this.clonersWithId = clonersWithId; this.clonersWithoutId = clonersWithoutId; @@ -377,16 +357,10 @@ public class DeepCloner { @SuppressWarnings("unchecked") Function c = (Function) getFromClassRespectingHierarchy(this.constructors, clazz); if (c == null) { - @SuppressWarnings("unchecked") - Supplier s = (Supplier) getFromClassRespectingHierarchy(this.parameterlessConstructors, clazz); - if (s == null) { - try { - res = clazz.newInstance(); - } catch (InstantiationException | IllegalAccessException ex) { - res = null; - } - } else { - res = s.get(); + try { + res = clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException ex) { + res = null; } } else { res = c.apply(this); diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java index 4f32abb813..e1b57680ea 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java @@ -80,10 +80,10 @@ public class ConcurrentHashMapStorageProviderFactory implements AmphibianProvide private final static DeepCloner CLONER = new DeepCloner.Builder() .genericCloner(Serialization::from) - .constructorDC(MapClientEntityImpl.class, MapClientEntityImpl::new) - .constructor(MapProtocolMapperEntity.class, MapProtocolMapperEntityImpl::new) - .constructorDC(MapGroupEntityImpl.class, MapGroupEntityImpl::new) - .constructorDC(MapRoleEntityImpl.class, MapRoleEntityImpl::new) + .constructor(MapClientEntityImpl.class, MapClientEntityImpl::new) + .constructor(MapProtocolMapperEntity.class, MapProtocolMapperEntityImpl::new) + .constructor(MapGroupEntityImpl.class, MapGroupEntityImpl::new) + .constructor(MapRoleEntityImpl.class, MapRoleEntityImpl::new) .build(); private static final Map KEY_CONVERTORS = new HashMap<>(); diff --git a/model/map/src/test/java/org/keycloak/models/map/client/MapClientEntityClonerTest.java b/model/map/src/test/java/org/keycloak/models/map/client/MapClientEntityClonerTest.java index 166053231d..c4b4be04d3 100644 --- a/model/map/src/test/java/org/keycloak/models/map/client/MapClientEntityClonerTest.java +++ b/model/map/src/test/java/org/keycloak/models/map/client/MapClientEntityClonerTest.java @@ -38,7 +38,7 @@ import static org.keycloak.models.map.common.DeepCloner.DUMB_CLONER; public class MapClientEntityClonerTest { private final static DeepCloner CLONER = new DeepCloner.Builder() - .constructorDC(MapClientEntityImpl.class, MapClientEntityImpl::new) + .constructor(MapClientEntityImpl.class, MapClientEntityImpl::new) .constructor(MapProtocolMapperEntity.class, MapProtocolMapperEntityImpl::new) .build();