17 changed files with 365 additions and 596 deletions
@ -1,98 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2011 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. |
|
||||||
* 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.springframework.data.mongodb.core.convert; |
|
||||||
|
|
||||||
import java.util.HashMap; |
|
||||||
import java.util.Map; |
|
||||||
import java.util.Map.Entry; |
|
||||||
|
|
||||||
import org.springframework.data.util.ClassTypeInformation; |
|
||||||
import org.springframework.data.util.TypeInformation; |
|
||||||
import org.springframework.util.Assert; |
|
||||||
|
|
||||||
/** |
|
||||||
* {@link TypeMapper} allowing to configure a {@link Map} containing {@link Class} to {@link String} mappings that will |
|
||||||
* be used to map the values found under the configured type key (see {@link DefaultTypeMapper#setTypeKey(String)}. This |
|
||||||
* allows declarative type mapping in a Spring config file for example. |
|
||||||
* |
|
||||||
* @author Oliver Gierke |
|
||||||
*/ |
|
||||||
public class ConfigurableTypeMapper extends DefaultTypeMapper { |
|
||||||
|
|
||||||
private final Map<TypeInformation<?>, String> typeMap; |
|
||||||
private boolean handleUnmappedClasses = false; |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a new {@link ConfigurableTypeMapper} for the given type map. |
|
||||||
* |
|
||||||
* @param sourceTypeMap must not be {@literal null}. |
|
||||||
*/ |
|
||||||
public ConfigurableTypeMapper(Map<? extends Class<?>, String> sourceTypeMap) { |
|
||||||
|
|
||||||
Assert.notNull(sourceTypeMap); |
|
||||||
|
|
||||||
this.typeMap = new HashMap<TypeInformation<?>, String>(sourceTypeMap.size()); |
|
||||||
|
|
||||||
for (Entry<? extends Class<?>, String> entry : sourceTypeMap.entrySet()) { |
|
||||||
TypeInformation<?> key = ClassTypeInformation.from(entry.getKey()); |
|
||||||
String value = entry.getValue(); |
|
||||||
|
|
||||||
if (typeMap.containsValue(value)) { |
|
||||||
throw new IllegalArgumentException(String.format( |
|
||||||
"Detected mapping ambiguity! String %s cannot be mapped to more than one type!", value)); |
|
||||||
} |
|
||||||
|
|
||||||
this.typeMap.put(key, value); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Configures whether to try to handle unmapped classes by simply writing the class' name or loading the class as |
|
||||||
* specified in the superclass. Defaults to {@literal false}. |
|
||||||
* |
|
||||||
* @param handleUnmappedClasses the handleUnmappedClasses to set |
|
||||||
*/ |
|
||||||
public void setHandleUnmappedClasses(boolean handleUnmappedClasses) { |
|
||||||
this.handleUnmappedClasses = handleUnmappedClasses; |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see org.springframework.data.mongodb.core.convert.DefaultTypeMapper#getTypeInformation(java.lang.String) |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected TypeInformation<?> getTypeInformation(String value) { |
|
||||||
|
|
||||||
for (Entry<TypeInformation<?>, String> entry : typeMap.entrySet()) { |
|
||||||
if (entry.getValue().equals(value)) { |
|
||||||
return entry.getKey(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return handleUnmappedClasses ? super.getTypeInformation(value) : null; |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see org.springframework.data.mongodb.core.convert.DefaultTypeMapper#getTypeString(org.springframework.data.util.TypeInformation) |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected String getTypeString(TypeInformation<?> typeInformation) { |
|
||||||
|
|
||||||
String key = typeMap.get(typeInformation); |
|
||||||
return key != null ? key : handleUnmappedClasses ? super.getTypeString(typeInformation) : null; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,122 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2011 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. |
||||||
|
* 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.springframework.data.mongodb.core.convert; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import org.springframework.data.convert.SimpleTypeInformationMapper; |
||||||
|
import org.springframework.data.convert.DefaultTypeMapper; |
||||||
|
import org.springframework.data.convert.TypeAliasAccessor; |
||||||
|
import org.springframework.data.convert.TypeInformationMapper; |
||||||
|
import org.springframework.data.mapping.PersistentEntity; |
||||||
|
import org.springframework.data.mapping.context.MappingContext; |
||||||
|
import org.springframework.data.util.ClassTypeInformation; |
||||||
|
import org.springframework.data.util.TypeInformation; |
||||||
|
import com.mongodb.BasicDBList; |
||||||
|
import com.mongodb.DBObject; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default implementation of {@link MongoTypeMapper} allowing configuration of the key to lookup and store type |
||||||
|
* information in {@link DBObject}. The key defaults to {@link #DEFAULT_TYPE_KEY}. Actual type-to-{@link String} |
||||||
|
* conversion and back is done in {@link #getTypeString(TypeInformation)} or {@link #getTypeInformation(String)} |
||||||
|
* respectively. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implements MongoTypeMapper { |
||||||
|
|
||||||
|
public static final String DEFAULT_TYPE_KEY = "_class"; |
||||||
|
@SuppressWarnings("rawtypes") |
||||||
|
private static final TypeInformation<List> LIST_TYPE_INFO = ClassTypeInformation.from(List.class); |
||||||
|
@SuppressWarnings("rawtypes") |
||||||
|
private static final TypeInformation<Map> MAP_TYPE_INFO = ClassTypeInformation.from(Map.class); |
||||||
|
private String typeKey = DEFAULT_TYPE_KEY; |
||||||
|
|
||||||
|
public DefaultMongoTypeMapper() { |
||||||
|
this(DEFAULT_TYPE_KEY, Arrays.asList(SimpleTypeInformationMapper.INSTANCE)); |
||||||
|
} |
||||||
|
|
||||||
|
public DefaultMongoTypeMapper(String typeKey) { |
||||||
|
super(new DBObjectTypeAliasAccessor(typeKey)); |
||||||
|
this.typeKey = typeKey; |
||||||
|
} |
||||||
|
|
||||||
|
public DefaultMongoTypeMapper(String typeKey, MappingContext<? extends PersistentEntity<?,?>, ?> mappingContext) { |
||||||
|
super(new DBObjectTypeAliasAccessor(typeKey), mappingContext, Arrays.asList(SimpleTypeInformationMapper.INSTANCE)); |
||||||
|
this.typeKey = typeKey; |
||||||
|
} |
||||||
|
|
||||||
|
public DefaultMongoTypeMapper(String typeKey, List<? extends TypeInformationMapper> mappers) { |
||||||
|
super(new DBObjectTypeAliasAccessor(typeKey), mappers); |
||||||
|
this.typeKey = typeKey; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.convert.MongoTypeMapper#isTypeKey(java.lang.String) |
||||||
|
*/ |
||||||
|
public boolean isTypeKey(String key) { |
||||||
|
return typeKey == null ? false : typeKey.equals(key); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.convert.DefaultTypeMapper#getFallbackTypeFor(java.lang.Object) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
protected TypeInformation<?> getFallbackTypeFor(DBObject source) { |
||||||
|
return source instanceof BasicDBList ? LIST_TYPE_INFO : MAP_TYPE_INFO; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
public static final class DBObjectTypeAliasAccessor implements TypeAliasAccessor<DBObject> { |
||||||
|
|
||||||
|
private final String typeKey; |
||||||
|
|
||||||
|
public DBObjectTypeAliasAccessor(String typeKey) { |
||||||
|
this.typeKey = typeKey; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* @see org.springframework.data.convert.TypeAliasAccessor#readAliasFrom(java.lang.Object) |
||||||
|
*/ |
||||||
|
public Object readAliasFrom(DBObject source) { |
||||||
|
|
||||||
|
if (source instanceof BasicDBList) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return source.get(typeKey); |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* @see org.springframework.data.convert.TypeAliasAccessor#writeTypeTo(java.lang.Object, java.lang.Object) |
||||||
|
*/ |
||||||
|
public void writeTypeTo(DBObject sink, Object alias) { |
||||||
|
if (typeKey != null) { |
||||||
|
sink.put(typeKey, alias); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -1,147 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2011 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. |
|
||||||
* 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.springframework.data.mongodb.core.convert; |
|
||||||
|
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
import org.springframework.data.util.ClassTypeInformation; |
|
||||||
import org.springframework.data.util.TypeInformation; |
|
||||||
import org.springframework.util.Assert; |
|
||||||
import org.springframework.util.ClassUtils; |
|
||||||
import org.springframework.util.StringUtils; |
|
||||||
|
|
||||||
import com.mongodb.BasicDBList; |
|
||||||
import com.mongodb.DBObject; |
|
||||||
|
|
||||||
/** |
|
||||||
* Default implementation of {@link TypeMapper} allowing configuration of the key to lookup and store type information |
|
||||||
* in {@link DBObject}. The key defaults to {@link #DEFAULT_TYPE_KEY}. Actual type-to-{@link String} conversion and back |
|
||||||
* is done in {@link #getTypeString(TypeInformation)} or {@link #getTypeInformation(String)} respectively. |
|
||||||
* |
|
||||||
* @author Oliver Gierke |
|
||||||
*/ |
|
||||||
public class DefaultTypeMapper implements TypeMapper { |
|
||||||
|
|
||||||
public static final String DEFAULT_TYPE_KEY = "_class"; |
|
||||||
@SuppressWarnings("rawtypes") |
|
||||||
private static final TypeInformation<List> LIST_TYPE_INFORMATION = ClassTypeInformation.from(List.class); |
|
||||||
|
|
||||||
private String typeKey = DEFAULT_TYPE_KEY; |
|
||||||
|
|
||||||
/** |
|
||||||
* Sets the key to store the type information under. If set to {@literal null} no type information will be stored in |
|
||||||
* the document. |
|
||||||
* |
|
||||||
* @param typeKey the typeKey to set |
|
||||||
*/ |
|
||||||
public void setTypeKey(String typeKey) { |
|
||||||
this.typeKey = typeKey; |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see org.springframework.data.mongodb.core.convert.TypeMapper#isTypeKey(java.lang.String) |
|
||||||
*/ |
|
||||||
public boolean isTypeKey(String key) { |
|
||||||
return typeKey == null ? false : typeKey.equals(key); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see org.springframework.data.mongodb.core.convert.TypeMapper#readType(com.mongodb.DBObject) |
|
||||||
*/ |
|
||||||
public TypeInformation<?> readType(DBObject dbObject) { |
|
||||||
|
|
||||||
if (dbObject instanceof BasicDBList) { |
|
||||||
return LIST_TYPE_INFORMATION; |
|
||||||
} |
|
||||||
|
|
||||||
if (typeKey == null) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
Object classToBeUsed = dbObject.get(typeKey); |
|
||||||
|
|
||||||
if (classToBeUsed == null) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
return getTypeInformation(classToBeUsed.toString()); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see org.springframework.data.mongodb.core.convert.TypeMapper#writeType(java.lang.Class, com.mongodb.DBObject) |
|
||||||
*/ |
|
||||||
public void writeType(Class<?> type, DBObject dbObject) { |
|
||||||
writeType(ClassTypeInformation.from(type), dbObject); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see org.springframework.data.mongodb.core.convert.TypeMapper#writeType(java.lang.Class, com.mongodb.DBObject) |
|
||||||
*/ |
|
||||||
public void writeType(TypeInformation<?> info, DBObject dbObject) { |
|
||||||
|
|
||||||
Assert.notNull(info); |
|
||||||
|
|
||||||
if (typeKey == null) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
String string = getTypeString(info); |
|
||||||
|
|
||||||
if (string != null) { |
|
||||||
dbObject.put(typeKey, getTypeString(info)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Turn the given type information into the String representation that shall be stored inside the {@link DBObject}. If |
|
||||||
* the returned String is {@literal null} no type information will be stored. Default implementation simply returns |
|
||||||
* the fully-qualified class name. |
|
||||||
* |
|
||||||
* @param typeInformation must not be {@literal null}. |
|
||||||
* @return the String representation to be stored or {@literal null} if no type information shall be stored. |
|
||||||
*/ |
|
||||||
protected String getTypeString(TypeInformation<?> typeInformation) { |
|
||||||
return typeInformation.getType().getName(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the {@link TypeInformation} that shall be used when the given {@link String} value is found as type hint. |
|
||||||
* The default implementation will simply interpret the given value as fully-qualified class name and try to load the |
|
||||||
* class. Will return {@literal null} in case the given {@link String} is empty. Will not be called in case no |
|
||||||
* {@link String} was found for the configured type key at all. |
|
||||||
* |
|
||||||
* @param value the type to load, must not be {@literal null}. |
|
||||||
* @return the type to be used for the given {@link String} representation or {@literal null} if nothing found or the |
|
||||||
* class cannot be loaded. |
|
||||||
*/ |
|
||||||
protected TypeInformation<?> getTypeInformation(String value) { |
|
||||||
|
|
||||||
if (!StringUtils.hasText(value)) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
try { |
|
||||||
return ClassTypeInformation.from(ClassUtils.forName(value, null)); |
|
||||||
} catch (ClassNotFoundException e) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,40 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2010-2011 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. |
|
||||||
* 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.springframework.data.mongodb.core.convert; |
|
||||||
|
|
||||||
import com.mongodb.DBObject; |
|
||||||
|
|
||||||
/** |
|
||||||
* A MongoWriter is responsible for converting a native MongoDB DBObject to an object of type T. |
|
||||||
* |
|
||||||
* @param <T> the type of the object to convert from a DBObject |
|
||||||
* @author Mark Pollack |
|
||||||
* @author Thomas Risberg |
|
||||||
* @author Oliver Gierke |
|
||||||
*/ |
|
||||||
public interface MongoReader<T> { |
|
||||||
|
|
||||||
/** |
|
||||||
* Ready from the native MongoDB DBObject representation to an instance of the class T. The given type has to be the |
|
||||||
* starting point for marshalling the {@link DBObject} into it. So in case there's no real valid data inside |
|
||||||
* {@link DBObject} for the given type, just return an empty instance of the given type. |
|
||||||
* |
|
||||||
* @param clazz the type of the return value. Will never be {@literal null}. |
|
||||||
* @param dbo the {@link DBObject} to convert into a domain object. Might be {@literal null}. |
|
||||||
* @return the converted object. Might be {@literal null}. |
|
||||||
*/ |
|
||||||
<S extends T> S read(Class<S> clazz, DBObject dbo); |
|
||||||
} |
|
||||||
@ -0,0 +1,30 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2011 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. |
||||||
|
* 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.springframework.data.mongodb.core.convert; |
||||||
|
|
||||||
|
import org.springframework.data.convert.TypeMapper; |
||||||
|
|
||||||
|
import com.mongodb.DBObject; |
||||||
|
|
||||||
|
/** |
||||||
|
* Combining interface to express Mongo specific {@link TypeMapper} implementations will be {@link TypeKeyAware} as |
||||||
|
* well. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
public interface MongoTypeMapper extends TypeMapper<DBObject>, TypeKeyAware { |
||||||
|
|
||||||
|
} |
||||||
@ -1,60 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2011 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. |
|
||||||
* 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.springframework.data.mongodb.core.convert; |
|
||||||
|
|
||||||
import org.springframework.data.util.TypeInformation; |
|
||||||
|
|
||||||
import com.mongodb.DBObject; |
|
||||||
|
|
||||||
/** |
|
||||||
* Interface to define strategies how to store type information in a {@link DBObject}. |
|
||||||
* |
|
||||||
* @author Oliver Gierke |
|
||||||
*/ |
|
||||||
public interface TypeMapper { |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns whether the given key is the key being used as type key. |
|
||||||
* |
|
||||||
* @param key |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
boolean isTypeKey(String key); |
|
||||||
|
|
||||||
/** |
|
||||||
* Reads the {@link TypeInformation} from the given {@link DBObject}. |
|
||||||
* |
|
||||||
* @param dbObject must not be {@literal null}. |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
TypeInformation<?> readType(DBObject dbObject); |
|
||||||
|
|
||||||
/** |
|
||||||
* Writes type information for the given type into the given {@link DBObject}. |
|
||||||
* |
|
||||||
* @param type must not be {@literal null}. |
|
||||||
* @param dbObject must not be {@literal null}. |
|
||||||
*/ |
|
||||||
void writeType(Class<?> type, DBObject dbObject); |
|
||||||
|
|
||||||
/** |
|
||||||
* Writes type information for the given {@link TypeInformation} into the given {@link DBObject}. |
|
||||||
* |
|
||||||
* @param type must not be {@literal null}. |
|
||||||
* @param dbObject must not be {@literal null}. |
|
||||||
*/ |
|
||||||
void writeType(TypeInformation<?> type, DBObject dbObject); |
|
||||||
} |
|
||||||
@ -1,109 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2011 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. |
|
||||||
* 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.springframework.data.mongodb.core.convert; |
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*; |
|
||||||
import static org.junit.Assert.*; |
|
||||||
|
|
||||||
import java.util.Collections; |
|
||||||
import java.util.HashMap; |
|
||||||
import java.util.Map; |
|
||||||
|
|
||||||
import org.junit.Before; |
|
||||||
import org.junit.Test; |
|
||||||
import org.springframework.data.util.TypeInformation; |
|
||||||
|
|
||||||
import com.mongodb.BasicDBObject; |
|
||||||
import com.mongodb.DBObject; |
|
||||||
|
|
||||||
/** |
|
||||||
* Unit tests for {@link ConfigurableTypeMapper}. |
|
||||||
* |
|
||||||
* @author Oliver Gierke |
|
||||||
*/ |
|
||||||
public class ConfigurableTypeMapperUnitTests { |
|
||||||
|
|
||||||
ConfigurableTypeMapper mapper; |
|
||||||
|
|
||||||
@Before |
|
||||||
public void setUp() { |
|
||||||
mapper = new ConfigurableTypeMapper(Collections.singletonMap(String.class, "1")); |
|
||||||
} |
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class) |
|
||||||
public void rejectsNullTypeMap() { |
|
||||||
new ConfigurableTypeMapper(null); |
|
||||||
} |
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class) |
|
||||||
public void rejectsNonBijectionalMap() { |
|
||||||
Map<Class<?>, String> map = new HashMap<Class<?>, String>(); |
|
||||||
map.put(String.class, "1"); |
|
||||||
map.put(Object.class, "1"); |
|
||||||
|
|
||||||
new ConfigurableTypeMapper(map); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void writesMapKeyForType() { |
|
||||||
writesTypeToField(new BasicDBObject(), String.class, "1"); |
|
||||||
writesTypeToField(new BasicDBObject(), Object.class, null); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void writesClassNamesForUnmappedValuesIfConfigured() { |
|
||||||
mapper.setHandleUnmappedClasses(true); |
|
||||||
writesTypeToField(new BasicDBObject(), String.class, "1"); |
|
||||||
writesTypeToField(new BasicDBObject(), Object.class, Object.class.getName()); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void readsTypeForMapKey() { |
|
||||||
readsTypeFromField(new BasicDBObject(DefaultTypeMapper.DEFAULT_TYPE_KEY, "1"), String.class); |
|
||||||
readsTypeFromField(new BasicDBObject(DefaultTypeMapper.DEFAULT_TYPE_KEY, "unmapped"), null); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void readsTypeLoadingClassesForUnmappedTypesIfConfigured() { |
|
||||||
mapper.setHandleUnmappedClasses(true); |
|
||||||
readsTypeFromField(new BasicDBObject(DefaultTypeMapper.DEFAULT_TYPE_KEY, "1"), String.class); |
|
||||||
readsTypeFromField(new BasicDBObject(DefaultTypeMapper.DEFAULT_TYPE_KEY, Object.class.getName()), Object.class); |
|
||||||
} |
|
||||||
|
|
||||||
private void readsTypeFromField(DBObject dbObject, Class<?> type) { |
|
||||||
|
|
||||||
TypeInformation<?> typeInfo = mapper.readType(dbObject); |
|
||||||
|
|
||||||
if (type != null) { |
|
||||||
assertThat(typeInfo, is(notNullValue())); |
|
||||||
assertThat(typeInfo.getType(), is(typeCompatibleWith(type))); |
|
||||||
} else { |
|
||||||
assertThat(typeInfo, is(nullValue())); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void writesTypeToField(DBObject dbObject, Class<?> type, Object value) { |
|
||||||
|
|
||||||
mapper.writeType(type, dbObject); |
|
||||||
|
|
||||||
if (value == null) { |
|
||||||
assertThat(dbObject.keySet().isEmpty(), is(true)); |
|
||||||
} else { |
|
||||||
assertThat(dbObject.containsField(DefaultTypeMapper.DEFAULT_TYPE_KEY), is(true)); |
|
||||||
assertThat(dbObject.get(DefaultTypeMapper.DEFAULT_TYPE_KEY), is(value)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,124 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2011 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. |
||||||
|
* 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.springframework.data.mongodb.core.convert; |
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*; |
||||||
|
import static org.junit.Assert.*; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collections; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
import org.springframework.data.convert.SimpleTypeInformationMapper; |
||||||
|
import org.springframework.data.convert.ConfigurableTypeInformationMapper; |
||||||
|
import org.springframework.data.util.TypeInformation; |
||||||
|
|
||||||
|
import com.mongodb.BasicDBObject; |
||||||
|
import com.mongodb.DBObject; |
||||||
|
|
||||||
|
/** |
||||||
|
* Unit tests for {@link ConfigurableTypeMapper}. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
public class DefaultMongoTypeMapperUnitTests { |
||||||
|
|
||||||
|
ConfigurableTypeInformationMapper configurableTypeInformationMapper; |
||||||
|
SimpleTypeInformationMapper simpleTypeInformationMapper; |
||||||
|
|
||||||
|
|
||||||
|
DefaultMongoTypeMapper typeMapper; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() { |
||||||
|
|
||||||
|
configurableTypeInformationMapper = new ConfigurableTypeInformationMapper(Collections.singletonMap(String.class, "1")); |
||||||
|
simpleTypeInformationMapper = SimpleTypeInformationMapper.INSTANCE; |
||||||
|
|
||||||
|
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList( |
||||||
|
configurableTypeInformationMapper)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void defaultInstanceWritesClasses() { |
||||||
|
|
||||||
|
typeMapper = new DefaultMongoTypeMapper(); |
||||||
|
writesTypeToField(new BasicDBObject(), String.class, String.class.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void defaultInstanceReadsClasses() { |
||||||
|
typeMapper = new DefaultMongoTypeMapper(); |
||||||
|
DBObject dbObject = new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, String.class.getName()); |
||||||
|
readsTypeFromField(dbObject, String.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void writesMapKeyForType() { |
||||||
|
writesTypeToField(new BasicDBObject(), String.class, "1"); |
||||||
|
writesTypeToField(new BasicDBObject(), Object.class, null); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void writesClassNamesForUnmappedValuesIfConfigured() { |
||||||
|
|
||||||
|
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList( |
||||||
|
configurableTypeInformationMapper, simpleTypeInformationMapper)); |
||||||
|
|
||||||
|
writesTypeToField(new BasicDBObject(), String.class, "1"); |
||||||
|
writesTypeToField(new BasicDBObject(), Object.class, Object.class.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void readsTypeForMapKey() { |
||||||
|
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "1"), String.class); |
||||||
|
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "unmapped"), null); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void readsTypeLoadingClassesForUnmappedTypesIfConfigured() { |
||||||
|
|
||||||
|
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList( |
||||||
|
configurableTypeInformationMapper, simpleTypeInformationMapper)); |
||||||
|
|
||||||
|
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "1"), String.class); |
||||||
|
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Object.class.getName()), Object.class); |
||||||
|
} |
||||||
|
|
||||||
|
private void readsTypeFromField(DBObject dbObject, Class<?> type) { |
||||||
|
|
||||||
|
TypeInformation<?> typeInfo = typeMapper.readType(dbObject); |
||||||
|
|
||||||
|
if (type != null) { |
||||||
|
assertThat(typeInfo, is(notNullValue())); |
||||||
|
assertThat(typeInfo.getType(), is(typeCompatibleWith(type))); |
||||||
|
} else { |
||||||
|
assertThat(typeInfo, is(nullValue())); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void writesTypeToField(DBObject dbObject, Class<?> type, Object value) { |
||||||
|
|
||||||
|
typeMapper.writeType(type, dbObject); |
||||||
|
|
||||||
|
if (value == null) { |
||||||
|
assertThat(dbObject.keySet().isEmpty(), is(true)); |
||||||
|
} else { |
||||||
|
assertThat(dbObject.containsField(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY), is(true)); |
||||||
|
assertThat(dbObject.get(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY), is(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue