commit
58ad6b1a40
6 changed files with 54 additions and 12 deletions
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue