keycloak-memoizeit
Changes
connections/mongo/src/main/java/org/keycloak/connections/mongo/api/types/MapperRegistry.java 8(+8 -0)
connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/BasicDBObjectToMapMapper.java 36(+32 -4)
Details
diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/api/types/MapperRegistry.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/api/types/MapperRegistry.java
index bafda1e..90c9355 100755
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/api/types/MapperRegistry.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/api/types/MapperRegistry.java
@@ -47,6 +47,10 @@ public class MapperRegistry {
public <S> S convertDBObjectToApplicationObject(MapperContext<Object, S> context) {
+ if (context.getObjectToConvert() == null) {
+ return null;
+ }
+
Object dbObject = context.getObjectToConvert();
Class<?> expectedApplicationObjectType = context.getExpectedReturnType();
@@ -74,6 +78,10 @@ public class MapperRegistry {
public <S> S convertApplicationObjectToDBObject(Object applicationObject, Class<S> expectedDBObjectType) {
+ if (applicationObject == null) {
+ return null;
+ }
+
Class<?> appObjectType = applicationObject.getClass();
Mapper<Object, S> mapper = (Mapper<Object, S>)getAppConverterForType(appObjectType, appObjectMappers);
if (mapper == null) {
diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/MongoStoreImpl.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/MongoStoreImpl.java
index a496c0b..94049f5 100755
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/MongoStoreImpl.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/MongoStoreImpl.java
@@ -79,9 +79,9 @@ public class MongoStoreImpl implements MongoStore {
mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, Set.class));
mapperRegistry.addDBObjectMapper(new BasicDBListToSetMapper(mapperRegistry));
- mapperRegistry.addAppObjectMapper(new MapMapper(HashMap.class));
- mapperRegistry.addAppObjectMapper(new MapMapper(Map.class));
- mapperRegistry.addDBObjectMapper(new BasicDBObjectToMapMapper());
+ mapperRegistry.addAppObjectMapper(new MapMapper(mapperRegistry, HashMap.class));
+ mapperRegistry.addAppObjectMapper(new MapMapper(mapperRegistry, Map.class));
+ mapperRegistry.addDBObjectMapper(new BasicDBObjectToMapMapper(mapperRegistry));
// Enum converters
mapperRegistry.addAppObjectMapper(new EnumToStringMapper());
diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/BasicDBObjectToMapMapper.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/BasicDBObjectToMapMapper.java
index 14ada88..316d771 100644
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/BasicDBObjectToMapMapper.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/BasicDBObjectToMapMapper.java
@@ -3,31 +3,44 @@ package org.keycloak.connections.mongo.impl.types;
import com.mongodb.BasicDBObject;
import org.keycloak.connections.mongo.api.types.Mapper;
import org.keycloak.connections.mongo.api.types.MapperContext;
+import org.keycloak.connections.mongo.api.types.MapperRegistry;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
- * For now, there is support just for convert to Map<String, simpleType>
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class BasicDBObjectToMapMapper implements Mapper<BasicDBObject, Map> {
+ private final MapperRegistry mapperRegistry;
+
+ public BasicDBObjectToMapMapper(MapperRegistry mapperRegistry) {
+ this.mapperRegistry = mapperRegistry;
+ }
+
@Override
public Map convertObject(MapperContext<BasicDBObject, Map> context) {
BasicDBObject dbObjectToConvert = context.getObjectToConvert();
+ Type expectedElementValueType = context.getGenericTypes().get(1);
HashMap<String, Object> result = new HashMap<String, Object>();
for (Map.Entry<String, Object> entry : dbObjectToConvert.entrySet()) {
String key = entry.getKey();
- Object value = entry.getValue();
+ Object dbValue = entry.getValue();
// Workaround as manually inserted numbers into mongo may be treated as "Double"
- if (value instanceof Double && context.getGenericTypes().get(1) == Integer.class) {
- value = ((Double)value).intValue();
+ if (dbValue instanceof Double && expectedElementValueType == Integer.class) {
+ dbValue = ((Double)dbValue).intValue();
}
+ MapperContext<Object, Object> newContext = getMapperContext(dbValue, expectedElementValueType);
+ Object value = mapperRegistry.convertDBObjectToApplicationObject(newContext);
+
if (key.contains(MapMapper.DOT_PLACEHOLDER)) {
key = key.replaceAll(MapMapper.DOT_PLACEHOLDER, ".");
}
@@ -46,4 +59,19 @@ public class BasicDBObjectToMapMapper implements Mapper<BasicDBObject, Map> {
public Class<Map> getExpectedReturnType() {
return Map.class;
}
+
+ private MapperContext<Object, Object> getMapperContext(Object dbValue, Type expectedElementValueType) {
+ if (expectedElementValueType instanceof Class) {
+ Class<?> clazz = (Class<?>) expectedElementValueType;
+ return new MapperContext<>(dbValue, clazz, null);
+ } else if (expectedElementValueType instanceof ParameterizedType) {
+ ParameterizedType parameterized = (ParameterizedType) expectedElementValueType;
+ Class<?> expectedClazz = (Class<?>) parameterized.getRawType();
+ Type[] generics = parameterized.getActualTypeArguments();
+
+ return new MapperContext<>(dbValue, expectedClazz, Arrays.asList(generics));
+ } else {
+ throw new IllegalArgumentException("Unexpected type: '" + expectedElementValueType + "' for converting " + dbValue);
+ }
+ }
}
diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/MapMapper.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/MapMapper.java
index d4f0d29..5ec174b 100644
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/MapMapper.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/MapMapper.java
@@ -3,6 +3,7 @@ package org.keycloak.connections.mongo.impl.types;
import com.mongodb.BasicDBObject;
import org.keycloak.connections.mongo.api.types.Mapper;
import org.keycloak.connections.mongo.api.types.MapperContext;
+import org.keycloak.connections.mongo.api.types.MapperRegistry;
import java.util.Map;
import java.util.Set;
@@ -17,30 +18,34 @@ public class MapMapper<T extends Map> implements Mapper<T, BasicDBObject> {
// Just some dummy way of encoding . character as it's not allowed by mongo in key fields
static final String DOT_PLACEHOLDER = "###";
+ private final MapperRegistry mapperRegistry;
private final Class<T> mapType;
- public MapMapper(Class<T> mapType) {
+ public MapMapper(MapperRegistry mapperRegistry, Class<T> mapType) {
+ this.mapperRegistry = mapperRegistry;
this.mapType = mapType;
}
@Override
public BasicDBObject convertObject(MapperContext<T, BasicDBObject> context) {
T mapToConvert = context.getObjectToConvert();
- return convertMap(mapToConvert);
+ return convertMap(mapToConvert, mapperRegistry);
}
- public static BasicDBObject convertMap(Map mapToConvert) {
+ public static BasicDBObject convertMap(Map mapToConvert, MapperRegistry mapperRegistry) {
BasicDBObject dbObject = new BasicDBObject();
Set<Map.Entry> entries = mapToConvert.entrySet();
for (Map.Entry entry : entries) {
String key = (String)entry.getKey();
Object value = entry.getValue();
+ Object dbValue = mapperRegistry==null ? entry.getValue() : mapperRegistry.convertApplicationObjectToDBObject(value, Object.class);
+
if (key.contains(".")) {
key = key.replaceAll("\\.", DOT_PLACEHOLDER);
}
- dbObject.put(key, value);
+ dbObject.put(key, dbValue);
}
return dbObject;
}
diff --git a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java
index abaae4c..aedd9f9 100644
--- a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java
+++ b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java
@@ -249,7 +249,7 @@ public class Update1_2_0_Beta1 extends Update {
dbMapper.put("protocolMapper", protocolMapper.getProtocolMapper());
Map<String, String> config = protocolMapper.getConfig();
- BasicDBObject dbConfig = MapMapper.convertMap(config);
+ BasicDBObject dbConfig = MapMapper.convertMap(config, null);
dbMapper.put("config", dbConfig);
dbProtocolMappers.add(dbMapper);
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 3a63687..823a51b 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -1310,6 +1310,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
model.setDescription(entity.getDescription());
model.setBuiltIn(entity.isBuiltIn());
model.setTopLevel(entity.isTopLevel());
+ model.setProviderId(entity.getProviderId());
return model;
}