Stripping extra, obsolete stuff.

This commit is contained in:
Jon Brisbin
2011-03-07 16:40:03 -06:00
committed by J. Brisbin
parent 8949d53252
commit 40ef4d7ad9
3 changed files with 15 additions and 347 deletions

View File

@@ -19,48 +19,31 @@ package org.springframework.data.document.mongodb.convert;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.types.CodeWScope;
import org.bson.types.ObjectId;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.document.mongodb.mapping.MappingException;
import org.springframework.data.document.mongodb.mapping.MappingIntrospector;
import org.springframework.data.document.mongodb.mapping.MongoMappingContext;
import org.springframework.data.mapping.annotation.Id;
import org.springframework.data.mapping.annotation.Persistent;
import org.springframework.data.mapping.annotation.Transient;
import org.springframework.data.mapping.annotation.Value;
import org.springframework.data.mapping.model.PersistentEntity;
import org.springframework.data.mapping.model.PersistentProperty;
import org.springframework.data.mapping.model.types.Association;
import org.springframework.data.mapping.model.types.Simple;
import org.springframework.data.mapping.reflect.ClassPropertyFetcher;
import org.springframework.data.mapping.reflect.ReflectionUtils;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
@@ -69,40 +52,8 @@ import java.util.regex.Pattern;
public class MappingMongoConverter implements MongoConverter, ApplicationContextAware {
protected static final Log log = LogFactory.getLog(MappingMongoConverter.class);
protected static final Set<String> SIMPLE_TYPES;
protected static final ConcurrentMap<Class<?>, Map<String, Field>> fieldsByName = new ConcurrentHashMap<Class<?>, Map<String, Field>>();
static {
Set<String> basics = new HashSet<String>();
basics.add(boolean.class.getName());
basics.add(long.class.getName());
basics.add(short.class.getName());
basics.add(int.class.getName());
basics.add(byte.class.getName());
basics.add(float.class.getName());
basics.add(double.class.getName());
basics.add(char.class.getName());
basics.add(Boolean.class.getName());
basics.add(Long.class.getName());
basics.add(Short.class.getName());
basics.add(Integer.class.getName());
basics.add(Byte.class.getName());
basics.add(Float.class.getName());
basics.add(Double.class.getName());
basics.add(Character.class.getName());
basics.add(String.class.getName());
basics.add(java.util.Date.class.getName());
basics.add(Locale.class.getName());
basics.add(Class.class.getName());
basics.add(DBRef.class.getName());
basics.add(Pattern.class.getName());
basics.add(CodeWScope.class.getName());
basics.add(ObjectId.class.getName());
// TODO check on enums..
basics.add(Enum.class.getName());
SIMPLE_TYPES = Collections.unmodifiableSet(basics);
}
protected GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
protected MongoMappingContext mappingContext;
protected ApplicationContext applicationContext;
@@ -237,9 +188,13 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
if (MappingIntrospector.isSimpleType(newObj.getClass())) {
dbo.put(name, newObj);
} else {
if (newObj.getClass().isAssignableFrom(Collection.class)) {
if (newObj.getClass().isArray() || newObj.getClass().isAssignableFrom(Collection.class)) {
BasicDBList dbList = new BasicDBList();
write(newObj, dbList);
for (Object collObj : (Object[]) (newObj.getClass().isArray() ? newObj : ((Collection) newObj).toArray())) {
BasicDBObject newDbObj = new BasicDBObject();
write(collObj, newDbObj);
dbList.add(newDbObj);
}
dbo.put(name, dbList);
} else {
DBObject newDbObj = new BasicDBObject();
@@ -272,20 +227,6 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
this.applicationContext = applicationContext;
}
protected boolean isTransientField(Field f) {
return (Modifier.isTransient(f.getModifiers()) || null != f.getAnnotation(Transient.class) || null != f.getAnnotation(Autowired.class));
}
protected boolean isPersistentProperty(Object obj, PropertyDescriptor descriptor) {
try {
Field f = obj.getClass().getDeclaredField(descriptor.getName());
return false;
} catch (NoSuchFieldException e) {
return false;
}
}
protected void initializeConverters() {
if (!conversionService.canConvert(ObjectId.class, String.class)) {
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
@@ -299,9 +240,6 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
conversionService.addConverter(IntegerToIdConverter.INSTANCE);
conversionService.addConverter(IdToIntegerConverter.INSTANCE);
}
if (!conversionService.canConvert(Object.class, DBObject.class)) {
conversionService.addConverter(new ObjectToDBObjectConverter());
}
}
protected Object getValueInternal(String name, Class<?> type, DBObject dbo, StandardEvaluationContext ctx, Expression spelExpr) {
@@ -320,16 +258,6 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
return o;
}
protected static boolean isSimpleType(Class<?> propertyType) {
if (propertyType == null) {
return false;
}
if (propertyType.isArray()) {
return isSimpleType(propertyType.getComponentType());
}
return SIMPLE_TYPES.contains(propertyType.getName());
}
/**
* Simple singleton to convert {@link ObjectId}s to their {@link String} representation.
*
@@ -404,84 +332,4 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
}
}
protected class ObjectToDBObjectConverter implements Converter<Object, DBObject> {
private final DBObject dbo;
public ObjectToDBObjectConverter() {
this.dbo = null;
}
public ObjectToDBObjectConverter(DBObject dbo) {
this.dbo = dbo;
}
public DBObject convert(Object source) {
DBObject dbo;
if (source instanceof Collection) {
Collection c = (Collection) source;
dbo = (null == this.dbo ? new BasicDBList() : this.dbo);
for (Object o : c) {
if (isSimpleType(o.getClass())) {
((BasicDBList) dbo).add(o);
} else {
((BasicDBList) dbo).add(convert(o));
}
}
} else if (source instanceof Map) {
Map<Object, Object> m = (Map) source;
dbo = (null == this.dbo ? new BasicDBObject() : this.dbo);
for (Map.Entry<Object, Object> entry : m.entrySet()) {
String key = (entry.getKey() instanceof String ? entry.getKey().toString() : conversionService.convert(entry.getKey(), String.class));
if (isSimpleType(entry.getValue().getClass())) {
dbo.put(key, entry.getValue());
} else {
dbo.put(key, convert(entry.getValue()));
}
}
} else {
dbo = (null == this.dbo ? new BasicDBObject() : this.dbo);
if (!fieldsByName.containsKey(source.getClass())) {
Map<String, Field> fields = new HashMap<String, Field>();
for (Field f : source.getClass().getDeclaredFields()) {
if (!"class".equals(f.getName())) {
ReflectionUtils.makeAccessible(f);
fields.put(f.getName(), f);
}
}
fieldsByName.put(source.getClass(), fields);
}
try {
for (PropertyDescriptor descriptor : Introspector.getBeanInfo(source.getClass()).getPropertyDescriptors()) {
Field f = fieldsByName.get(source.getClass()).get(descriptor.getName());
if (null != f && !isTransientField(f)) {
try {
Object o;
if (null != descriptor.getReadMethod()) {
o = descriptor.getReadMethod().invoke(source);
} else {
o = f.get(source);
}
if (null != o && isSimpleType(o.getClass())) {
dbo.put(descriptor.getName(), o);
} else if (null != o) {
dbo.put(descriptor.getName(), convert(o));
} else {
// Value was NULL, skip it
}
} catch (InvocationTargetException e) {
throw new RuntimeException("Error converting " + source + " to DBObject");
} catch (IllegalAccessException e) {
throw new RuntimeException("Error converting " + source + " to DBObject");
}
}
}
} catch (IntrospectionException e) {
throw new RuntimeException("Error converting " + source + " to DBObject");
}
}
return dbo;
}
}
}

View File

@@ -1,177 +0,0 @@
/*
* Copyright (c) 2011 by the original author(s).
*
* 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.document.mongodb.convert;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
import org.bson.types.CodeWScope;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.mapping.annotation.Transient;
import org.springframework.data.mapping.reflect.ReflectionUtils;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
public class SimplePojoDBObjectConverter {
protected static final Set<String> SIMPLE_TYPES;
static {
Set<String> basics = new HashSet<String>();
basics.add(boolean.class.getName());
basics.add(long.class.getName());
basics.add(short.class.getName());
basics.add(int.class.getName());
basics.add(byte.class.getName());
basics.add(float.class.getName());
basics.add(double.class.getName());
basics.add(char.class.getName());
basics.add(Boolean.class.getName());
basics.add(Long.class.getName());
basics.add(Short.class.getName());
basics.add(Integer.class.getName());
basics.add(Byte.class.getName());
basics.add(Float.class.getName());
basics.add(Double.class.getName());
basics.add(Character.class.getName());
basics.add(String.class.getName());
basics.add(java.util.Date.class.getName());
basics.add(Locale.class.getName());
basics.add(Class.class.getName());
basics.add(DBRef.class.getName());
basics.add(Pattern.class.getName());
basics.add(CodeWScope.class.getName());
basics.add(ObjectId.class.getName());
// TODO check on enums..
basics.add(Enum.class.getName());
SIMPLE_TYPES = Collections.unmodifiableSet(basics);
}
protected static final ConcurrentMap<Class<?>, Map<String, Field>> fieldsByName = new ConcurrentHashMap<Class<?>, Map<String, Field>>();
protected GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
public SimplePojoDBObjectConverter() {
}
public GenericConversionService getConversionService() {
return conversionService;
}
public void setConversionService(GenericConversionService conversionService) {
this.conversionService = conversionService;
}
public static boolean isSimpleType(Class<?> propertyType) {
if (propertyType == null) {
return false;
}
if (propertyType.isArray()) {
return isSimpleType(propertyType.getComponentType());
}
return SIMPLE_TYPES.contains(propertyType.getName());
}
public static boolean isTransientField(Field f) {
return (Modifier.isTransient(f.getModifiers()) || null != f.getAnnotation(Transient.class) || null != f.getAnnotation(Autowired.class));
}
public DBObject convert(Object source, DBObject existing) throws Exception {
DBObject dbo;
if (source instanceof Collection) {
Collection c = (Collection) source;
dbo = (null == existing ? new BasicDBList() : existing);
for (Object o : c) {
if (isSimpleType(o.getClass())) {
((BasicDBList) dbo).add(o);
} else {
((BasicDBList) dbo).add(convert(o, null));
}
}
} else if (source instanceof Map) {
Map<Object, Object> m = (Map) source;
dbo = (null == existing ? new BasicDBObject() : existing);
for (Map.Entry<Object, Object> entry : m.entrySet()) {
String key = (entry.getKey() instanceof String ? entry.getKey().toString() : conversionService.convert(entry.getKey(), String.class));
if (isSimpleType(entry.getValue().getClass())) {
dbo.put(key, entry.getValue());
} else {
dbo.put(key, convert(entry.getValue(), null));
}
}
} else {
dbo = (null == existing ? new BasicDBObject() : existing);
if (!fieldsByName.containsKey(source.getClass())) {
Map<String, Field> fields = new HashMap<String, Field>();
for (Field f : source.getClass().getDeclaredFields()) {
if (!"class".equals(f.getName())) {
ReflectionUtils.makeAccessible(f);
fields.put(f.getName(), f);
}
}
fieldsByName.put(source.getClass(), fields);
}
try {
for (PropertyDescriptor descriptor : Introspector.getBeanInfo(source.getClass()).getPropertyDescriptors()) {
Field f = fieldsByName.get(source.getClass()).get(descriptor.getName());
if (null != f && !isTransientField(f)) {
try {
Object o;
if (null != descriptor.getReadMethod()) {
o = descriptor.getReadMethod().invoke(source);
} else {
o = f.get(source);
}
if (null != o && isSimpleType(o.getClass())) {
dbo.put(descriptor.getName(), o);
} else if (null != o) {
dbo.put(descriptor.getName(), convert(o, null));
} else {
// Value was NULL, skip it
}
} catch (InvocationTargetException e) {
throw new RuntimeException("Error converting " + source + " to DBObject");
} catch (IllegalAccessException e) {
throw new RuntimeException("Error converting " + source + " to DBObject");
}
}
}
} catch (IntrospectionException e) {
throw new RuntimeException("Error converting " + source + " to DBObject");
}
}
return dbo;
}
}

View File

@@ -17,7 +17,6 @@
package org.springframework.data.document.mongodb.mapping;
import com.mongodb.DBRef;
import com.sun.org.apache.xalan.internal.extensions.ExpressionContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.types.CodeWScope;
@@ -28,12 +27,9 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.data.mapping.annotation.*;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.Assert;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
@@ -124,10 +120,11 @@ public class MappingIntrospector<T> {
fld.setAccessible(true);
if (!isTransientField(fld)) {
if (fld.isAnnotationPresent(Id.class)) {
if (null != idField) {
throw new IllegalStateException("You cannot have two fields in a domain object annotated with Id! " + clazz);
if (null == idField) {
idField = fld;
} else {
log.warn("Only the first field found with the @Id annotation will be considered the ID. Ignoring " + idField);
}
idField = fld;
continue;
} else if (null == idField && fldType.equals(ObjectId.class)) {
// Respect fields of the MongoDB ObjectId type