Add Map support to reflection based serializer
This commit is contained in:
@@ -52,20 +52,29 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> implements
|
|||||||
this.db = db;
|
this.db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MongoTemplate(DB db, String defaultCollectionName) {
|
||||||
|
super();
|
||||||
|
this.db = db;
|
||||||
|
this.defaultCollectionName = defaultCollectionName;
|
||||||
|
}
|
||||||
|
|
||||||
public MongoTemplate(DB db, MongoConverter mongoConverter) {
|
public MongoTemplate(DB db, MongoConverter mongoConverter) {
|
||||||
this(db);
|
this(db);
|
||||||
this.mongoConverter = mongoConverter;
|
this.mongoConverter = mongoConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MongoTemplate(DB db, String defaultCollectionName, MongoConverter mongoConverter) {
|
||||||
|
this(db);
|
||||||
|
this.mongoConverter = mongoConverter;
|
||||||
|
this.defaultCollectionName = defaultCollectionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getDefaultCollectionName() {
|
public String getDefaultCollectionName() {
|
||||||
return defaultCollectionName;
|
return defaultCollectionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultCollectionName(String defaultCollection) {
|
|
||||||
this.defaultCollectionName = defaultCollection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void executeCommand(String jsonCommand) {
|
public void executeCommand(String jsonCommand) {
|
||||||
executeCommand((DBObject)JSON.parse(jsonCommand));
|
executeCommand((DBObject)JSON.parse(jsonCommand));
|
||||||
@@ -80,6 +89,20 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> T executeInSession(DBCallback<T> action) {
|
||||||
|
DB db = getConnection();
|
||||||
|
db.requestStart();
|
||||||
|
try {
|
||||||
|
return action.doInDB(db);
|
||||||
|
} catch (MongoException e) {
|
||||||
|
//TODO refine exception thrown to capture last error.
|
||||||
|
CommandResult result = db.getLastError();
|
||||||
|
throw new InvalidDataAccessApiUsageException("Error accessing DB " + db + ":" + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
db.requestDone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DBCollection createCollection(String collectionName) {
|
public DBCollection createCollection(String collectionName) {
|
||||||
try {
|
try {
|
||||||
return getConnection().createCollection(collectionName, null);
|
return getConnection().createCollection(collectionName, null);
|
||||||
@@ -96,6 +119,14 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DBCollection getCollection(String collectionName) {
|
||||||
|
try {
|
||||||
|
return getConnection().getCollection(collectionName);
|
||||||
|
} catch (MongoException e) {
|
||||||
|
throw new InvalidDataAccessApiUsageException("Error creating collection " + collectionName + ": " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean collectionExists(String collectionName) {
|
public boolean collectionExists(String collectionName) {
|
||||||
try {
|
try {
|
||||||
@@ -194,6 +225,7 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
public <T> List<T> queryForList(String collectionName, DBObject query, Class<T> targetClass) {
|
public <T> List<T> queryForList(String collectionName, DBObject query, Class<T> targetClass) {
|
||||||
DBCollection collection = getConnection().getCollection(collectionName);
|
DBCollection collection = getConnection().getCollection(collectionName);
|
||||||
|
|||||||
@@ -16,10 +16,19 @@
|
|||||||
package org.springframework.datastore.document.mongodb;
|
package org.springframework.datastore.document.mongodb;
|
||||||
|
|
||||||
import java.beans.PropertyDescriptor;
|
import java.beans.PropertyDescriptor;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.GenericArrayType;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.lang.reflect.TypeVariable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -147,6 +156,7 @@ public class SimpleMongoConverter implements MongoConverter {
|
|||||||
writeValue(dbo, keyToUse, value);
|
writeValue(dbo, keyToUse, value);
|
||||||
// dbo.put(keyToUse, value);
|
// dbo.put(keyToUse, value);
|
||||||
} else {
|
} else {
|
||||||
|
//TODO exclude Class properties from consideration
|
||||||
logger.warn("Unable to map property " + pd.getName()
|
logger.warn("Unable to map property " + pd.getName()
|
||||||
+ ". Skipping.");
|
+ ". Skipping.");
|
||||||
}
|
}
|
||||||
@@ -171,7 +181,7 @@ public class SimpleMongoConverter implements MongoConverter {
|
|||||||
|
|
||||||
private void writeCompoundValue(DBObject dbo, String keyToUse, Object value) {
|
private void writeCompoundValue(DBObject dbo, String keyToUse, Object value) {
|
||||||
if (value instanceof Map) {
|
if (value instanceof Map) {
|
||||||
// Should write a collection!
|
writeMap(dbo, keyToUse, (Map<String, Object>)value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (value instanceof Collection) {
|
if (value instanceof Collection) {
|
||||||
@@ -179,8 +189,30 @@ public class SimpleMongoConverter implements MongoConverter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DBObject nestedDbo = new BasicDBObject();
|
DBObject nestedDbo = new BasicDBObject();
|
||||||
dbo.put(keyToUse, nestedDbo);
|
|
||||||
write(value, nestedDbo);
|
write(value, nestedDbo);
|
||||||
|
dbo.put(keyToUse, nestedDbo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeMap(DBObject dbo, String keyToUse, Map<String, Object> map) {
|
||||||
|
//TODO support non-string based keys as long as there is a Spring Converter obj->string and (optionally) string->obj
|
||||||
|
DBObject dboToPopulate = null;
|
||||||
|
if (keyToUse != null) {
|
||||||
|
dboToPopulate = new BasicDBObject();
|
||||||
|
} else {
|
||||||
|
dboToPopulate = dbo;
|
||||||
|
}
|
||||||
|
if (map != null) {
|
||||||
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
|
Object entryValue = entry.getValue();
|
||||||
|
if (!isSimpleType(entryValue.getClass())) {
|
||||||
|
writeCompoundValue(dboToPopulate, entry.getKey(), entryValue);
|
||||||
|
} else {
|
||||||
|
dboToPopulate.put(entry.getKey(), entryValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbo.put(keyToUse, dboToPopulate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -190,13 +222,15 @@ public class SimpleMongoConverter implements MongoConverter {
|
|||||||
|
|
||||||
public Object read(Class<? extends Object> clazz, DBObject dbo) {
|
public Object read(Class<? extends Object> clazz, DBObject dbo) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Assert.state(clazz != null, "Mapped class was not specified");
|
Assert.state(clazz != null, "Mapped class was not specified");
|
||||||
Object mappedObject = BeanUtils.instantiate(clazz);
|
Object mappedObject = BeanUtils.instantiate(clazz);
|
||||||
BeanWrapper bw = PropertyAccessorFactory
|
BeanWrapper bw = PropertyAccessorFactory
|
||||||
.forBeanPropertyAccess(mappedObject);
|
.forBeanPropertyAccess(mappedObject);
|
||||||
initBeanWrapper(bw);
|
initBeanWrapper(bw);
|
||||||
|
|
||||||
// Iterate over properties of the object.
|
// Iterate over properties of the object.b
|
||||||
// TODO iterate over the properties of DBObject and support nested property names with SpEL
|
// TODO iterate over the properties of DBObject and support nested property names with SpEL
|
||||||
// e.g. { "parameters.p1" : "1" , "count" : 5.0}
|
// e.g. { "parameters.p1" : "1" , "count" : 5.0}
|
||||||
PropertyDescriptor[] propertyDescriptors = BeanUtils
|
PropertyDescriptor[] propertyDescriptors = BeanUtils
|
||||||
@@ -225,32 +259,56 @@ public class SimpleMongoConverter implements MongoConverter {
|
|||||||
return mappedObject;
|
return mappedObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readValue(BeanWrapper bw, PropertyDescriptor pd, DBObject dbo) {
|
protected void readValue(BeanWrapper bw, PropertyDescriptor pd, DBObject dbo) {
|
||||||
|
|
||||||
Object value = dbo.get(pd.getName());
|
Object value = dbo.get(pd.getName());
|
||||||
// is not a simple type.
|
// is not a simple type.
|
||||||
if (!isSimpleType(value.getClass())) {
|
if (!isSimpleType(value.getClass())) {
|
||||||
bw.setPropertyValue(
|
bw.setPropertyValue(pd.getName(),readCompoundValue(pd, (DBObject) dbo.get(pd.getName())));
|
||||||
pd.getName(),
|
|
||||||
readCompoundValue(pd.getPropertyType(),
|
|
||||||
(DBObject) dbo.get(pd.getName())));
|
|
||||||
} else {
|
} else {
|
||||||
bw.setPropertyValue(pd.getName(), value);
|
bw.setPropertyValue(pd.getName(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object readCompoundValue(Class<?> propertyClazz, DBObject dbo) {
|
private Object readCompoundValue(PropertyDescriptor pd, DBObject dbo) {
|
||||||
|
Class propertyClazz = pd.getPropertyType();
|
||||||
if (Map.class.isAssignableFrom(propertyClazz)) {
|
if (Map.class.isAssignableFrom(propertyClazz)) {
|
||||||
// Should read a map!
|
//TODO assure is assignable to BasicDBObject
|
||||||
return null;
|
return readMap(pd, (BasicDBObject)dbo, getGenericParameterClass(pd.getWriteMethod()).get(1) );
|
||||||
}
|
}
|
||||||
if (Collection.class.isAssignableFrom(propertyClazz)) {
|
if (Collection.class.isAssignableFrom(propertyClazz)) {
|
||||||
// Should read a collection!
|
// Should read a collection!
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// single document
|
|
||||||
return read(propertyClazz, dbo);
|
return read(propertyClazz, dbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Map createMap() {
|
||||||
|
return new HashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map readMap(PropertyDescriptor pd, BasicDBObject dbo, Class valueClazz) {
|
||||||
|
Class propertyClazz = pd.getPropertyType();
|
||||||
|
Map map = createMap();
|
||||||
|
for (Map.Entry entry : dbo.entrySet()) {
|
||||||
|
Object entryValue = entry.getValue();
|
||||||
|
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(entryValue);
|
||||||
|
initBeanWrapper(bw);
|
||||||
|
|
||||||
|
if (!isSimpleType(entryValue.getClass())) {
|
||||||
|
map.put((String)entry.getKey(), read(valueClazz, (DBObject) entryValue));
|
||||||
|
//Can do some reflection tricks here -
|
||||||
|
//throw new RuntimeException("User types not supported yet as values for Maps");
|
||||||
|
} else {
|
||||||
|
map.put((String)entry.getKey(), entryValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected void setObjectIdOnObject(BeanWrapper bw, PropertyDescriptor pd,
|
protected void setObjectIdOnObject(BeanWrapper bw, PropertyDescriptor pd,
|
||||||
ObjectId value) {
|
ObjectId value) {
|
||||||
// TODO strategy for setting the id field. suggest looking for public
|
// TODO strategy for setting the id field. suggest looking for public
|
||||||
@@ -276,4 +334,43 @@ public class SimpleMongoConverter implements MongoConverter {
|
|||||||
bw.setConversionService(conversionService);
|
bw.setConversionService(conversionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Class> getGenericParameterClass(Method setMethod) {
|
||||||
|
List<Class> actualGenericParameterTypes = new ArrayList<Class>();
|
||||||
|
Type[] genericParameterTypes = setMethod.getGenericParameterTypes();
|
||||||
|
|
||||||
|
for(Type genericParameterType : genericParameterTypes){
|
||||||
|
if(genericParameterType instanceof ParameterizedType){
|
||||||
|
ParameterizedType aType = (ParameterizedType) genericParameterType;
|
||||||
|
Type[] parameterArgTypes = aType.getActualTypeArguments();
|
||||||
|
for(Type parameterArgType : parameterArgTypes){
|
||||||
|
if (parameterArgType instanceof GenericArrayType)
|
||||||
|
{
|
||||||
|
Class arrayType = (Class) ((GenericArrayType) parameterArgType).getGenericComponentType();
|
||||||
|
actualGenericParameterTypes.add(Array.newInstance(arrayType, 0).getClass());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (parameterArgType instanceof ParameterizedType) {
|
||||||
|
ParameterizedType paramTypeArgs = (ParameterizedType) parameterArgType;
|
||||||
|
actualGenericParameterTypes.add((Class)paramTypeArgs.getRawType());
|
||||||
|
} else {
|
||||||
|
if (parameterArgType instanceof TypeVariable) {
|
||||||
|
throw new RuntimeException("Can not map " + ((TypeVariable) parameterArgType).getName());
|
||||||
|
} else {
|
||||||
|
if (parameterArgType instanceof Class) {
|
||||||
|
actualGenericParameterTypes.add((Class) parameterArgType);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Can not map " + parameterArgType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actualGenericParameterTypes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,28 @@ package org.springframework.datastore.document.mongodb;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class Portfolio {
|
public class Portfolio {
|
||||||
|
|
||||||
private String portfolioName;
|
private String portfolioName;
|
||||||
private User user;
|
private User user;
|
||||||
private List trades;
|
private List trades;
|
||||||
|
private Map<String, Integer> positions;
|
||||||
|
private Map<String, Person> portfolioManagers;
|
||||||
|
|
||||||
|
public Map<String, Person> getPortfolioManagers() {
|
||||||
|
return portfolioManagers;
|
||||||
|
}
|
||||||
|
public void setPortfolioManagers(Map<String, Person> portfolioManagers) {
|
||||||
|
this.portfolioManagers = portfolioManagers;
|
||||||
|
}
|
||||||
|
public Map<String, Integer> getPositions() {
|
||||||
|
return positions;
|
||||||
|
}
|
||||||
|
public void setPositions(Map<String, Integer> positions) {
|
||||||
|
this.positions = positions;
|
||||||
|
}
|
||||||
public Portfolio() {
|
public Portfolio() {
|
||||||
trades = new ArrayList();
|
trades = new ArrayList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,17 +15,24 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.datastore.document.mongodb;
|
package org.springframework.datastore.document.mongodb;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.GenericArrayType;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.lang.reflect.TypeVariable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
|
|
||||||
|
|
||||||
public class SimpleMongoConverterTests {
|
public class SimpleMongoConverterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -51,7 +58,8 @@ public class SimpleMongoConverterTests {
|
|||||||
SimpleMongoConverter converter = createConverter();
|
SimpleMongoConverter converter = createConverter();
|
||||||
DBObject dbo = new BasicDBObject();
|
DBObject dbo = new BasicDBObject();
|
||||||
converter.write(p, dbo);
|
converter.write(p, dbo);
|
||||||
Assert.assertEquals("High Risk Trading Account", dbo.get("portfolioName"));
|
Assert.assertEquals("High Risk Trading Account",
|
||||||
|
dbo.get("portfolioName"));
|
||||||
Assert.assertTrue(dbo.containsField("user"));
|
Assert.assertTrue(dbo.containsField("user"));
|
||||||
|
|
||||||
Portfolio cp = (Portfolio) converter.read(Portfolio.class, dbo);
|
Portfolio cp = (Portfolio) converter.read(Portfolio.class, dbo);
|
||||||
@@ -61,24 +69,56 @@ public class SimpleMongoConverterTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void objectWithMap() {
|
||||||
|
Portfolio p = createPortfolioWithPositions();
|
||||||
|
SimpleMongoConverter converter = createConverter();
|
||||||
|
DBObject dbo = new BasicDBObject();
|
||||||
|
converter.write(p, dbo);
|
||||||
|
|
||||||
|
Portfolio cp = (Portfolio) converter.read(Portfolio.class, dbo);
|
||||||
|
Assert.assertEquals("High Risk Trading Account", cp.getPortfolioName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void objectWithMapContainingNonPrimitiveTypeAsValue() {
|
||||||
|
Portfolio p = createPortfolioWithManagers();
|
||||||
|
SimpleMongoConverter converter = createConverter();
|
||||||
|
DBObject dbo = new BasicDBObject();
|
||||||
|
converter.write(p, dbo);
|
||||||
|
|
||||||
|
Portfolio cp = (Portfolio) converter.read(Portfolio.class, dbo);
|
||||||
|
Assert.assertEquals("High Risk Trading Account", cp.getPortfolioName());
|
||||||
|
}
|
||||||
|
|
||||||
private SimpleMongoConverter createConverter() {
|
private SimpleMongoConverter createConverter() {
|
||||||
SimpleMongoConverter converter = new SimpleMongoConverter();
|
SimpleMongoConverter converter = new SimpleMongoConverter();
|
||||||
return converter;
|
return converter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
protected Portfolio createPortfolioWithPositions() {
|
||||||
public void instanceOfTests() {
|
|
||||||
List<String> list = new ArrayList<String>();
|
|
||||||
Assert.assertTrue(list instanceof Collection);
|
|
||||||
|
|
||||||
List objList = new ArrayList();
|
|
||||||
Assert.assertTrue(objList instanceof Collection);
|
|
||||||
|
|
||||||
|
|
||||||
|
Portfolio portfolio = new Portfolio();
|
||||||
|
portfolio.setPortfolioName("High Risk Trading Account");
|
||||||
|
Map<String, Integer> positions = new HashMap<String, Integer>();
|
||||||
|
positions.put("CSCO", 1);
|
||||||
|
portfolio.setPositions(positions);
|
||||||
|
return portfolio;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Portfolio createPortfolioWithNoTrades()
|
protected Portfolio createPortfolioWithManagers() {
|
||||||
{
|
|
||||||
|
Portfolio portfolio = new Portfolio();
|
||||||
|
portfolio.setPortfolioName("High Risk Trading Account");
|
||||||
|
Map<String, Person> managers = new HashMap<String, Person>();
|
||||||
|
Person p1 = new Person();
|
||||||
|
p1.setFirstName("Mark");
|
||||||
|
managers.put("CSCO", p1);
|
||||||
|
portfolio.setPortfolioManagers(managers);
|
||||||
|
return portfolio;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Portfolio createPortfolioWithNoTrades() {
|
||||||
Portfolio portfolio = new Portfolio();
|
Portfolio portfolio = new Portfolio();
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setUserName("Joe Trader");
|
user.setUserName("Joe Trader");
|
||||||
@@ -87,4 +127,65 @@ public class SimpleMongoConverterTests {
|
|||||||
portfolio.setPortfolioName("High Risk Trading Account");
|
portfolio.setPortfolioName("High Risk Trading Account");
|
||||||
return portfolio;
|
return portfolio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReflection() {
|
||||||
|
Portfolio p = createPortfolioWithManagers();
|
||||||
|
Method method = ReflectionUtils.findMethod(Portfolio.class, "setPortfolioManagers", Map.class);
|
||||||
|
Assert.assertNotNull(method);
|
||||||
|
List<Class> paramClass = getGenericParameterClass(method);
|
||||||
|
System.out.println(paramClass);
|
||||||
|
/*
|
||||||
|
Type t = method.getGenericReturnType();
|
||||||
|
if (t instanceof ParameterizedType) {
|
||||||
|
ParameterizedType pt = (ParameterizedType) t;
|
||||||
|
Type paramType = pt.getActualTypeArguments()[1];
|
||||||
|
if (paramType instanceof ParameterizedType) {
|
||||||
|
ParameterizedType paramPtype = (ParameterizedType) pt;
|
||||||
|
System.out.println(paramPtype.getRawType());
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
// Assert.assertNotNull(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class> getGenericParameterClass(Method setMethod) {
|
||||||
|
List<Class> actualGenericParameterTypes = new ArrayList<Class>();
|
||||||
|
Type[] genericParameterTypes = setMethod.getGenericParameterTypes();
|
||||||
|
|
||||||
|
for(Type genericParameterType : genericParameterTypes){
|
||||||
|
if(genericParameterType instanceof ParameterizedType){
|
||||||
|
ParameterizedType aType = (ParameterizedType) genericParameterType;
|
||||||
|
Type[] parameterArgTypes = aType.getActualTypeArguments();
|
||||||
|
for(Type parameterArgType : parameterArgTypes){
|
||||||
|
if (parameterArgType instanceof GenericArrayType)
|
||||||
|
{
|
||||||
|
Class arrayType = (Class) ((GenericArrayType) parameterArgType).getGenericComponentType();
|
||||||
|
actualGenericParameterTypes.add(Array.newInstance(arrayType, 0).getClass());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (parameterArgType instanceof ParameterizedType) {
|
||||||
|
ParameterizedType paramTypeArgs = (ParameterizedType) parameterArgType;
|
||||||
|
actualGenericParameterTypes.add((Class)paramTypeArgs.getRawType());
|
||||||
|
} else {
|
||||||
|
if (parameterArgType instanceof TypeVariable) {
|
||||||
|
throw new RuntimeException("Can not map " + ((TypeVariable) parameterArgType).getName());
|
||||||
|
} else {
|
||||||
|
if (parameterArgType instanceof Class) {
|
||||||
|
actualGenericParameterTypes.add((Class) parameterArgType);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Can not map " + parameterArgType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actualGenericParameterTypes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.springframework.datastore.document.mongodb.analytics;
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -10,6 +11,7 @@ import java.util.Map;
|
|||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.datastore.document.analytics.ControllerCounter;
|
||||||
import org.springframework.datastore.document.analytics.MvcEvent;
|
import org.springframework.datastore.document.analytics.MvcEvent;
|
||||||
import org.springframework.datastore.document.analytics.Parameters;
|
import org.springframework.datastore.document.analytics.Parameters;
|
||||||
import org.springframework.datastore.document.mongodb.MongoTemplate;
|
import org.springframework.datastore.document.mongodb.MongoTemplate;
|
||||||
@@ -18,12 +20,14 @@ import org.springframework.datastore.document.mongodb.query.Query;
|
|||||||
|
|
||||||
import com.mongodb.BasicDBList;
|
import com.mongodb.BasicDBList;
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.BasicDBObjectBuilder;
|
||||||
import com.mongodb.DB;
|
import com.mongodb.DB;
|
||||||
import com.mongodb.DBCollection;
|
import com.mongodb.DBCollection;
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
import com.mongodb.MongoException;
|
import com.mongodb.MongoException;
|
||||||
import com.mongodb.QueryBuilder;
|
import com.mongodb.QueryBuilder;
|
||||||
|
import com.mongodb.WriteResult;
|
||||||
|
|
||||||
public class MvcAnalyticsTests {
|
public class MvcAnalyticsTests {
|
||||||
|
|
||||||
@@ -33,11 +37,12 @@ public class MvcAnalyticsTests {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
Mongo m = new Mongo();
|
Mongo m = new Mongo();
|
||||||
DB db = m.getDB("mvc");
|
DB db = m.getDB("mvc");
|
||||||
mongoTemplate = new MongoTemplate(db);
|
mongoTemplate = new MongoTemplate(db, "mvc");
|
||||||
mongoTemplate.setDefaultCollectionName("mvc");
|
|
||||||
mongoTemplate.afterPropertiesSet();
|
mongoTemplate.afterPropertiesSet();
|
||||||
// mongoTemplate.dropCollection("mvc");
|
// mongoTemplate.dropCollection("mvc");
|
||||||
// mongoTemplate.createCollection("mvc");
|
// mongoTemplate.createCollection("mvc");
|
||||||
|
//mongoTemplate.dropCollection("counters");
|
||||||
|
//mongoTemplate.createCollection("counters");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -49,28 +54,24 @@ public class MvcAnalyticsTests {
|
|||||||
createAndStoreForP1(3, 3);
|
createAndStoreForP1(3, 3);
|
||||||
createAndStoreForP1(8, 4);
|
createAndStoreForP1(8, 4);
|
||||||
|
|
||||||
|
List<MvcEvent> mvcEvents = mongoTemplate.queryForCollection("mvc",
|
||||||
List<MvcEvent> mvcEvents = mongoTemplate.queryForCollection("mvc", MvcEvent.class);
|
MvcEvent.class);
|
||||||
Assert.assertEquals(22, mvcEvents.size());
|
Assert.assertEquals(22, mvcEvents.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
*
|
||||||
var start = new Date(2010,9,1);
|
* var start = new Date(2010,9,1); var end = new Date(2010,11,1);
|
||||||
var end = new Date(2010,11,1);
|
* db.mvc.group( { cond: {"action": "addFavoriteRestaurant", "date": {$gte:
|
||||||
db.mvc.group(
|
* start, $lt: end}} , key: {"parameters.p1": true} , initial: {count: 0} ,
|
||||||
{ cond: {"action": "addFavoriteRestaurant", "date": {$gte: start, $lt: end}}
|
* reduce: function(doc, out){ out.count++; } } );
|
||||||
, key: {"parameters.p1": true}
|
|
||||||
, initial: {count: 0}
|
|
||||||
, reduce: function(doc, out){ out.count++; }
|
|
||||||
} );
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void listAll() {
|
public void listAll() {
|
||||||
List<MvcEvent> mvcEvents = mongoTemplate.queryForCollection("mvc", MvcEvent.class);
|
List<MvcEvent> mvcEvents = mongoTemplate.queryForCollection("mvc",
|
||||||
|
MvcEvent.class);
|
||||||
for (MvcEvent mvcEvent : mvcEvents) {
|
for (MvcEvent mvcEvent : mvcEvents) {
|
||||||
System.out.println(mvcEvent.getDate());
|
System.out.println(mvcEvent.getDate());
|
||||||
}
|
}
|
||||||
@@ -80,7 +81,8 @@ db.mvc.group(
|
|||||||
@Test
|
@Test
|
||||||
public void groupQuery() {
|
public void groupQuery() {
|
||||||
// This circumvents exception translation
|
// This circumvents exception translation
|
||||||
DBCollection collection = mongoTemplate.getConnection().getCollection("mvc");
|
DBCollection collection = mongoTemplate.getConnection().getCollection(
|
||||||
|
"mvc");
|
||||||
|
|
||||||
// QueryBuilder qb = new QueryBuilder();
|
// QueryBuilder qb = new QueryBuilder();
|
||||||
// qb.start("date").greaterThan(object)
|
// qb.start("date").greaterThan(object)
|
||||||
@@ -94,22 +96,27 @@ db.mvc.group(
|
|||||||
endDate.set(Calendar.MONTH, 12);
|
endDate.set(Calendar.MONTH, 12);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
QueryBuilder qb = new QueryBuilder();
|
* QueryBuilder qb = new QueryBuilder(); Query q =
|
||||||
Query q = qb.find("date").gte(startDate.getTime()).lt(endDate.getTime()).and("action").is("addFavoriteRestaurant").build();
|
* qb.find("date").gte(startDate
|
||||||
DBObject cond2 = q.getQueryObject();
|
* .getTime()).lt(endDate.getTime()).and("action"
|
||||||
|
* ).is("addFavoriteRestaurant").build(); DBObject cond2 =
|
||||||
|
* q.getQueryObject();
|
||||||
*/
|
*/
|
||||||
DBObject cond = QueryBuilder.start("date").greaterThanEquals(startDate.getTime()).lessThan(endDate.getTime()).and("action").is("addFavoriteRestaurant").get();
|
DBObject cond = QueryBuilder.start("date")
|
||||||
|
.greaterThanEquals(startDate.getTime())
|
||||||
|
.lessThan(endDate.getTime()).and("action")
|
||||||
|
.is("addFavoriteRestaurant").get();
|
||||||
DBObject key = new BasicDBObject("parameters.p1", true);
|
DBObject key = new BasicDBObject("parameters.p1", true);
|
||||||
/*
|
/*
|
||||||
DBObject dateQ = new BasicDBObject();
|
* DBObject dateQ = new BasicDBObject(); dateQ.put("$gte",
|
||||||
dateQ.put("$gte", startDate.getTime());
|
* startDate.getTime()); dateQ.put("$lt", endDate.getTime()); DBObject
|
||||||
dateQ.put("$lt", endDate.getTime());
|
* cond = new BasicDBObject(); cond.put("action",
|
||||||
DBObject cond = new BasicDBObject();
|
* "addFavoriteRestaurant"); cond.put("date", dateQ);
|
||||||
cond.put("action", "addFavoriteRestaurant");
|
*/
|
||||||
cond.put("date", dateQ);*/
|
|
||||||
|
|
||||||
DBObject intitial = new BasicDBObject("count", 0);
|
DBObject intitial = new BasicDBObject("count", 0);
|
||||||
DBObject result = collection.group(key, cond, intitial, "function(doc, out){ out.count++; }");
|
DBObject result = collection.group(key, cond, intitial,
|
||||||
|
"function(doc, out){ out.count++; }");
|
||||||
if (result instanceof BasicDBList) {
|
if (result instanceof BasicDBList) {
|
||||||
BasicDBList dbList = (BasicDBList) result;
|
BasicDBList dbList = (BasicDBList) result;
|
||||||
for (Iterator iterator = dbList.iterator(); iterator.hasNext();) {
|
for (Iterator iterator = dbList.iterator(); iterator.hasNext();) {
|
||||||
@@ -121,6 +128,38 @@ db.mvc.group(
|
|||||||
System.out.println(result);
|
System.out.println(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void storeCounterInfo() {
|
||||||
|
|
||||||
|
BasicDBObject query = new BasicDBObject("name", "controller1");
|
||||||
|
|
||||||
|
BasicDBObject changes = new BasicDBObject();
|
||||||
|
changes.put("$set", new BasicDBObject("name", "controller1"));
|
||||||
|
changes.put("$inc", new BasicDBObject("count", 1));
|
||||||
|
|
||||||
|
//mongoTemplate.upsertAndModify(dbo("key","value"), inc("count",1));
|
||||||
|
//dbo(set("name","controller"), inc("count", 1));
|
||||||
|
|
||||||
|
///mongoTemplate.update(collection("counters")
|
||||||
|
|
||||||
|
WriteResult r = mongoTemplate.getCollection("counters").update(query, changes, true,false);
|
||||||
|
//{ "err" : "Modifiers and non-modifiers cannot be mixed" , "code" : 10154 , "n" : 0 , "ok" : 1.0}
|
||||||
|
//{ "err" : null , "updatedExisting" : false , "upserted" : { "$oid" : "4cba814a5a4900000000495d"} , "n" : 1 , "ok" : 1.0}
|
||||||
|
//{ "err" : null , "updatedExisting" : true , "n" : 1 , "ok" : 1.0}
|
||||||
|
System.out.println(r);
|
||||||
|
|
||||||
|
// changes = new BasicDBObject("methods", new BasicDBObject("find", 1));
|
||||||
|
// mongoTemplate.getCollection("counters").update(query, changes, true,
|
||||||
|
// false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateMethodCounter() {
|
||||||
|
DBObject query = new BasicDBObject("name", "controller1");
|
||||||
|
DBObject changes = new BasicDBObject("$inc", new BasicDBObject("methods.find", 1));
|
||||||
|
mongoTemplate.getConnection().getCollection("counters").update(query, changes, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
private void createAndStoreForP1(int dataSize, int p1) {
|
private void createAndStoreForP1(int dataSize, int p1) {
|
||||||
for (int i = 0; i < dataSize; i++) {
|
for (int i = 0; i < dataSize; i++) {
|
||||||
MvcEvent event = generateEvent(p1);
|
MvcEvent event = generateEvent(p1);
|
||||||
@@ -128,6 +167,16 @@ db.mvc.group(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ControllerCounter generateCounter() {
|
||||||
|
ControllerCounter cc = new ControllerCounter();
|
||||||
|
cc.setName("controller2");
|
||||||
|
cc.setCount(0);
|
||||||
|
Map<String, Integer> methods = new HashMap<String, Integer>();
|
||||||
|
methods.put("find", 1);
|
||||||
|
cc.setMethods(methods);
|
||||||
|
return cc;
|
||||||
|
}
|
||||||
|
|
||||||
private MvcEvent generateEvent(Integer p1) {
|
private MvcEvent generateEvent(Integer p1) {
|
||||||
MvcEvent event = new MvcEvent();
|
MvcEvent event = new MvcEvent();
|
||||||
|
|
||||||
@@ -145,4 +194,3 @@ db.mvc.group(
|
|||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user