DATACMNS-485 - API improvements to in TypeInformationMapper area.
The default implementations of the TypeInformation Mapper interfaces now work with ClassTypeInformation where possible to express they only map raw types effectively. Added TypeInformation.getRawTypeInformation() to easily turn whatever TypeInformation into the raw type representation. Changed ClassTypeInformation.from(…) to return ClassTypeInformations directly.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-12 the original author or authors.
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class ConfigurableTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
private final Map<TypeInformation<?>, Object> typeMap;
|
||||
private final Map<ClassTypeInformation<?>, Object> typeMap;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConfigurableTypeMapper} for the given type map.
|
||||
@@ -44,10 +44,10 @@ public class ConfigurableTypeInformationMapper implements TypeInformationMapper
|
||||
public ConfigurableTypeInformationMapper(Map<? extends Class<?>, String> sourceTypeMap) {
|
||||
|
||||
Assert.notNull(sourceTypeMap);
|
||||
this.typeMap = new HashMap<TypeInformation<?>, Object>(sourceTypeMap.size());
|
||||
this.typeMap = new HashMap<ClassTypeInformation<?>, Object>(sourceTypeMap.size());
|
||||
|
||||
for (Entry<? extends Class<?>, String> entry : sourceTypeMap.entrySet()) {
|
||||
TypeInformation<?> key = ClassTypeInformation.from(entry.getKey());
|
||||
ClassTypeInformation<?> key = ClassTypeInformation.from(entry.getKey());
|
||||
String value = entry.getValue();
|
||||
|
||||
if (typeMap.containsValue(value)) {
|
||||
@@ -71,13 +71,13 @@ public class ConfigurableTypeInformationMapper implements TypeInformationMapper
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.lang.Object)
|
||||
*/
|
||||
public TypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
public ClassTypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Entry<TypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
for (Entry<ClassTypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
if (entry.getValue().equals(alias)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class MappingContextTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
private final Map<TypeInformation<?>, Object> typeMap;
|
||||
private final Map<ClassTypeInformation<?>, Object> typeMap;
|
||||
private final MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext;
|
||||
|
||||
/**
|
||||
@@ -47,11 +47,11 @@ public class MappingContextTypeInformationMapper implements TypeInformationMappe
|
||||
|
||||
Assert.notNull(mappingContext);
|
||||
|
||||
this.typeMap = new HashMap<TypeInformation<?>, Object>();
|
||||
this.typeMap = new HashMap<ClassTypeInformation<?>, Object>();
|
||||
this.mappingContext = mappingContext;
|
||||
|
||||
for (PersistentEntity<?, ?> entity : mappingContext.getPersistentEntities()) {
|
||||
safelyAddToCache(entity.getTypeInformation(), entity.getTypeAlias());
|
||||
safelyAddToCache(entity.getTypeInformation().getRawTypeInformation(), entity.getTypeAlias());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class MappingContextTypeInformationMapper implements TypeInformationMappe
|
||||
}
|
||||
|
||||
Object alias = entity.getTypeAlias();
|
||||
safelyAddToCache(type, alias);
|
||||
safelyAddToCache(type.getRawTypeInformation(), alias);
|
||||
|
||||
return alias;
|
||||
}
|
||||
@@ -85,50 +85,49 @@ public class MappingContextTypeInformationMapper implements TypeInformationMappe
|
||||
* @param key must not be {@literal null}.
|
||||
* @param alias can be {@literal null}.
|
||||
*/
|
||||
private void safelyAddToCache(TypeInformation<?> key, Object alias) {
|
||||
private void safelyAddToCache(ClassTypeInformation<?> key, Object alias) {
|
||||
|
||||
if (alias == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TypeInformation<?> toStore = ClassTypeInformation.from(key.getType());
|
||||
Object existingAlias = typeMap.get(toStore);
|
||||
Object existingAlias = typeMap.get(key);
|
||||
|
||||
// Reject second alias for same type
|
||||
|
||||
if (existingAlias != null && !alias.equals(existingAlias)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Trying to register alias '%s', but found already registered alias '%s' for type %s!", alias, existingAlias,
|
||||
toStore));
|
||||
key));
|
||||
}
|
||||
|
||||
// Reject second type for same alias
|
||||
|
||||
if (typeMap.containsValue(alias)) {
|
||||
|
||||
for (Entry<TypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
if (entry.getValue().equals(alias) && !entry.getKey().equals(toStore)) {
|
||||
for (Entry<ClassTypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
if (entry.getValue().equals(alias) && !entry.getKey().equals(key)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Detected existing type mapping of %s to alias '%s' but attempted to bind the same alias to %s!",
|
||||
toStore, alias, entry.getKey()));
|
||||
"Detected existing type mapping of %s to alias '%s' but attempted to bind the same alias to %s!", key,
|
||||
alias, entry.getKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typeMap.put(toStore, alias);
|
||||
typeMap.put(key, alias);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.lang.Object)
|
||||
*/
|
||||
public TypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
public ClassTypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Entry<TypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
for (Entry<ClassTypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
if (entry.getValue().equals(alias)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
@@ -136,7 +135,7 @@ public class MappingContextTypeInformationMapper implements TypeInformationMappe
|
||||
|
||||
for (PersistentEntity<?, ?> entity : mappingContext.getPersistentEntities()) {
|
||||
if (alias.equals(entity.getTypeAlias())) {
|
||||
return entity.getTypeInformation();
|
||||
return entity.getTypeInformation().getRawTypeInformation();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,7 +33,7 @@ import org.springframework.util.StringUtils;
|
||||
public class SimpleTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
public static final SimpleTypeInformationMapper INSTANCE = new SimpleTypeInformationMapper();
|
||||
private static final Map<String, TypeInformation<?>> cache = new ConcurrentHashMap<String, TypeInformation<?>>();
|
||||
private static final Map<String, ClassTypeInformation<?>> cache = new ConcurrentHashMap<String, ClassTypeInformation<?>>();
|
||||
|
||||
/**
|
||||
* Returns the {@link TypeInformation} that shall be used when the given {@link String} value is found as type hint.
|
||||
@@ -44,7 +44,7 @@ public class SimpleTypeInformationMapper implements TypeInformationMapper {
|
||||
* @return the type to be used for the given {@link String} representation or {@literal null} if nothing found or the
|
||||
* class cannot be loaded.
|
||||
*/
|
||||
public TypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
public ClassTypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
|
||||
if (!(alias instanceof String)) {
|
||||
return null;
|
||||
@@ -56,7 +56,7 @@ public class SimpleTypeInformationMapper implements TypeInformationMapper {
|
||||
return null;
|
||||
}
|
||||
|
||||
TypeInformation<?> information = cache.get(value);
|
||||
ClassTypeInformation<?> information = cache.get(value);
|
||||
|
||||
if (information != null) {
|
||||
return information;
|
||||
|
||||
@@ -40,18 +40,18 @@ import org.springframework.util.ClassUtils;
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
|
||||
|
||||
public static final TypeInformation<Collection> COLLECTION = new ClassTypeInformation(Collection.class);
|
||||
public static final TypeInformation<List> LIST = new ClassTypeInformation(List.class);
|
||||
public static final TypeInformation<Set> SET = new ClassTypeInformation(Set.class);
|
||||
public static final TypeInformation<Map> MAP = new ClassTypeInformation(Map.class);
|
||||
public static final TypeInformation<Object> OBJECT = new ClassTypeInformation(Object.class);
|
||||
public static final ClassTypeInformation<Collection> COLLECTION = new ClassTypeInformation(Collection.class);
|
||||
public static final ClassTypeInformation<List> LIST = new ClassTypeInformation(List.class);
|
||||
public static final ClassTypeInformation<Set> SET = new ClassTypeInformation(Set.class);
|
||||
public static final ClassTypeInformation<Map> MAP = new ClassTypeInformation(Map.class);
|
||||
public static final ClassTypeInformation<Object> OBJECT = new ClassTypeInformation(Object.class);
|
||||
|
||||
private static final Map<Class<?>, Reference<TypeInformation<?>>> CACHE = Collections
|
||||
.synchronizedMap(new WeakHashMap<Class<?>, Reference<TypeInformation<?>>>());
|
||||
private static final Map<Class<?>, Reference<ClassTypeInformation<?>>> CACHE = Collections
|
||||
.synchronizedMap(new WeakHashMap<Class<?>, Reference<ClassTypeInformation<?>>>());
|
||||
|
||||
static {
|
||||
for (TypeInformation<?> info : Arrays.asList(COLLECTION, LIST, SET, MAP, OBJECT)) {
|
||||
CACHE.put(info.getType(), new WeakReference<TypeInformation<?>>(info));
|
||||
for (ClassTypeInformation<?> info : Arrays.asList(COLLECTION, LIST, SET, MAP, OBJECT)) {
|
||||
CACHE.put(info.getType(), new WeakReference<ClassTypeInformation<?>>(info));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,19 +64,19 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <S> TypeInformation<S> from(Class<S> type) {
|
||||
public static <S> ClassTypeInformation<S> from(Class<S> type) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
|
||||
Reference<TypeInformation<?>> cachedReference = CACHE.get(type);
|
||||
Reference<ClassTypeInformation<?>> cachedReference = CACHE.get(type);
|
||||
TypeInformation<?> cachedTypeInfo = cachedReference == null ? null : cachedReference.get();
|
||||
|
||||
if (cachedTypeInfo != null) {
|
||||
return (TypeInformation<S>) cachedTypeInfo;
|
||||
return (ClassTypeInformation<S>) cachedTypeInfo;
|
||||
}
|
||||
|
||||
TypeInformation<S> result = new ClassTypeInformation<S>(type);
|
||||
CACHE.put(type, new WeakReference<TypeInformation<?>>(result));
|
||||
ClassTypeInformation<S> result = new ClassTypeInformation<S>(type);
|
||||
CACHE.put(type, new WeakReference<ClassTypeInformation<?>>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -116,6 +116,15 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.util.TypeDiscoverer#getRawTypeInformation()
|
||||
*/
|
||||
@Override
|
||||
public ClassTypeInformation<?> getRawTypeInformation() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.util.TypeDiscoverer#isAssignableFrom(org.springframework.data.util.TypeInformation)
|
||||
|
||||
@@ -270,6 +270,15 @@ class TypeDiscoverer<S> implements TypeInformation<S> {
|
||||
return this.resolvedType;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.util.TypeInformation#getRawTypeInformation()
|
||||
*/
|
||||
@Override
|
||||
public ClassTypeInformation<?> getRawTypeInformation() {
|
||||
return ClassTypeInformation.from(getType()).getRawTypeInformation();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.util.TypeInformation#getActualType()
|
||||
|
||||
@@ -82,6 +82,14 @@ public interface TypeInformation<S> {
|
||||
*/
|
||||
Class<S> getType();
|
||||
|
||||
/**
|
||||
* Returns a {@link ClassTypeInformation} to represent the {@link TypeInformation} of the raw type of the current
|
||||
* instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ClassTypeInformation<?> getRawTypeInformation();
|
||||
|
||||
/**
|
||||
* Transparently returns the {@link java.util.Map} value type if the type is a {@link java.util.Map}, returns the
|
||||
* component type if the type {@link #isCollectionLike()} or the simple type if none of this applies.
|
||||
|
||||
Reference in New Issue
Block a user