DATAMONGO-1176 - Switch to Document API.

We use the Document API when interacting with the MongoDB Java Driver. This allows us to make use of new features and enables us to use the Codec API and prepares the project for future enhancements concerning the drivers the reactive API.
This commit is contained in:
Christoph Strobl
2016-04-04 12:54:08 +02:00
committed by Oliver Gierke
parent 4371760272
commit 2461575c52
213 changed files with 4320 additions and 3685 deletions

View File

@@ -29,7 +29,7 @@
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.0.0.BUILD-SNAPSHOT</springdata.commons>
<mongo>2.14.0</mongo>
<mongo>3.2.2</mongo>
</properties>
<developers>

View File

@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.crossstore;
import javax.persistence.EntityManagerFactory;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
@@ -29,10 +30,10 @@ import org.springframework.data.mongodb.core.CollectionCallback;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.util.ClassUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.result.DeleteResult;
/**
* @author Thomas Risberg
@@ -74,15 +75,15 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
String collName = getCollectionNameForEntity(entityClass);
final DBObject dbk = new BasicDBObject();
final Document dbk = new Document();
dbk.put(ENTITY_ID, id);
dbk.put(ENTITY_CLASS, entityClass.getName());
if (log.isDebugEnabled()) {
log.debug("Loading MongoDB data for {}", dbk);
}
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
for (DBObject dbo : collection.find(dbk)) {
public Object doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
for (Document dbo : collection.find(dbk)) {
String key = (String) dbo.get(ENTITY_FIELD_NAME);
if (log.isDebugEnabled()) {
log.debug("Processing key: {}", key);
@@ -143,27 +144,31 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
for (String key : cs.getValues().keySet()) {
if (key != null && !key.startsWith("_") && !key.equals(ChangeSetPersister.ID_KEY)) {
Object value = cs.getValues().get(key);
final DBObject dbQuery = new BasicDBObject();
final Document dbQuery = new Document();
dbQuery.put(ENTITY_ID, getPersistentId(entity, cs));
dbQuery.put(ENTITY_CLASS, entity.getClass().getName());
dbQuery.put(ENTITY_FIELD_NAME, key);
DBObject dbId = mongoTemplate.execute(collName, new CollectionCallback<DBObject>() {
public DBObject doInCollection(DBCollection collection) throws MongoException, DataAccessException {
return collection.findOne(dbQuery);
final Document dbId = mongoTemplate.execute(collName, new CollectionCallback<Document>() {
public Document doInCollection(MongoCollection<Document> collection)
throws MongoException, DataAccessException {
Document id = collection.find(dbQuery).first();
return id;
}
});
if (value == null) {
if (log.isDebugEnabled()) {
log.debug("Flush: removing: {}", dbQuery);
}
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
collection.remove(dbQuery);
public Object doInCollection(MongoCollection<Document> collection)
throws MongoException, DataAccessException {
DeleteResult dr = collection.deleteMany(dbQuery);
return null;
}
});
} else {
final DBObject dbDoc = new BasicDBObject();
final Document dbDoc = new Document();
dbDoc.putAll(dbQuery);
if (log.isDebugEnabled()) {
log.debug("Flush: saving: {}", dbQuery);
@@ -174,8 +179,18 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
dbDoc.put("_id", dbId.get("_id"));
}
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
collection.save(dbDoc);
public Object doInCollection(MongoCollection<Document> collection)
throws MongoException, DataAccessException {
if (dbId != null) {
collection.replaceOne(Filters.eq("_id", dbId.get("_id")), dbDoc);
} else {
if (dbDoc.containsKey("_id") && dbDoc.get("_id") == null) {
dbDoc.remove("_id");
}
collection.insertOne(dbDoc);
}
return null;
}
});

View File

@@ -18,6 +18,7 @@ package org.springframework.data.mongodb.crossstore;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.bson.Document;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -36,8 +37,6 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.mongodb.DBObject;
/**
* Integration tests for MongoDB cross-store persistence (mainly {@link MongoChangeSetPersister}).
*
@@ -48,14 +47,11 @@ import com.mongodb.DBObject;
@ContextConfiguration("classpath:/META-INF/spring/applicationContext.xml")
public class CrossStoreMongoTests {
@Autowired
MongoTemplate mongoTemplate;
@Autowired MongoTemplate mongoTemplate;
@PersistenceContext
EntityManager entityManager;
@PersistenceContext EntityManager entityManager;
@Autowired
PlatformTransactionManager transactionManager;
@Autowired PlatformTransactionManager transactionManager;
TransactionTemplate txTemplate;
@Before
@@ -187,7 +183,7 @@ public class CrossStoreMongoTests {
boolean weFound3 = false;
for (DBObject dbo : this.mongoTemplate.getCollection(mongoTemplate.getCollectionName(Person.class)).find()) {
for (Document dbo : this.mongoTemplate.getCollection(mongoTemplate.getCollectionName(Person.class)).find()) {
Assert.assertTrue(!dbo.get("_entity_id").equals(2L));
if (dbo.get("_entity_id").equals(3L)) {
weFound3 = true;

View File

@@ -20,7 +20,7 @@
<mongo:mapping-converter/>
<!-- Mongo config -->
<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
<bean id="mongo" class="org.springframework.data.mongodb.core.MongoClientFactoryBean">
<property name="host" value="localhost"/>
<property name="port" value="27017"/>
</bean>

View File

@@ -18,6 +18,7 @@
<properties>
<objenesis>1.3</objenesis>
<equalsverifier>1.5</equalsverifier>
<mongo>3.2.2</mongo>
</properties>
<dependencies>

View File

@@ -20,6 +20,7 @@ import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.core.MongoExceptionTranslator;
import com.mongodb.DB;
import com.mongodb.client.MongoDatabase;
/**
* Interface for factories creating {@link DB} instances.
@@ -35,7 +36,7 @@ public interface MongoDbFactory {
* @return
* @throws DataAccessException
*/
DB getDb() throws DataAccessException;
MongoDatabase getDb() throws DataAccessException;
/**
* Creates a {@link DB} instance to access the database with the given name.
@@ -44,7 +45,7 @@ public interface MongoDbFactory {
* @return
* @throws DataAccessException
*/
DB getDb(String dbName) throws DataAccessException;
MongoDatabase getDb(String dbName) throws DataAccessException;
/**
* Exposes a shared {@link MongoExceptionTranslator}.
@@ -52,4 +53,6 @@ public interface MongoDbFactory {
* @return will never be {@literal null}.
*/
PersistenceExceptionTranslator getExceptionTranslator();
DB getLegacyDb();
}

View File

@@ -32,7 +32,7 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.config.BeanComponentDefinitionBuilder;
import org.springframework.data.mongodb.core.MongoFactoryBean;
import org.springframework.data.mongodb.core.MongoClientFactoryBean;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
@@ -131,7 +131,7 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
*/
private BeanDefinition registerMongoBeanDefinition(Element element, ParserContext parserContext) {
BeanDefinitionBuilder mongoBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoFactoryBean.class);
BeanDefinitionBuilder mongoBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoClientFactoryBean.class);
setPropertyValue(mongoBuilder, element, "host");
setPropertyValue(mongoBuilder, element, "port");

View File

@@ -21,8 +21,6 @@ import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.Pair;
import com.mongodb.BulkWriteResult;
/**
* Bulk operations for insert/update/remove actions on a collection. These bulks operation are available since MongoDB
* 2.6 and make use of low level bulk commands on the protocol level. This interface defines a fluent API to add
@@ -141,5 +139,5 @@ public interface BulkOperations {
* @return Result of the bulk operation providing counters for inserts/updates etc.
* @throws {@link BulkOperationException} if an error occurred during bulk processing.
*/
BulkWriteResult execute();
com.mongodb.bulk.BulkWriteResult execute();
}

View File

@@ -15,12 +15,14 @@
*/
package org.springframework.data.mongodb.core;
import com.mongodb.DBCollection;
import com.mongodb.MongoException;
import org.bson.Document;
import org.springframework.dao.DataAccessException;
import com.mongodb.MongoException;
import com.mongodb.client.MongoCollection;
public interface CollectionCallback<T> {
T doInCollection(DBCollection collection) throws MongoException, DataAccessException;
T doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException;
}

View File

@@ -15,7 +15,10 @@
*/
package org.springframework.data.mongodb.core;
import org.bson.Document;
import com.mongodb.DBCursor;
import com.mongodb.client.FindIterable;
/**
* Simple callback interface to allow customization of a {@link DBCursor}.
@@ -29,5 +32,5 @@ interface CursorPreparer {
*
* @param cursor
*/
DBCursor prepare(DBCursor cursor);
FindIterable<Document> prepare(FindIterable<Document> cursor);
}

View File

@@ -15,11 +15,12 @@
*/
package org.springframework.data.mongodb.core;
import com.mongodb.DB;
import com.mongodb.MongoException;
import org.springframework.dao.DataAccessException;
import com.mongodb.MongoException;
import com.mongodb.client.MongoDatabase;
public interface DbCallback<T> {
T doInDB(DB db) throws MongoException, DataAccessException;
T doInDB(MongoDatabase db) throws MongoException, DataAccessException;
}

View File

@@ -15,9 +15,11 @@
*/
package org.springframework.data.mongodb.core;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bson.Document;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.core.query.Query;
@@ -26,12 +28,15 @@ import org.springframework.data.util.Pair;
import org.springframework.util.Assert;
import com.mongodb.BulkWriteException;
import com.mongodb.BulkWriteOperation;
import com.mongodb.BulkWriteRequestBuilder;
import com.mongodb.BulkWriteResult;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.WriteConcern;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.BulkWriteOptions;
import com.mongodb.client.model.DeleteManyModel;
import com.mongodb.client.model.InsertOneModel;
import com.mongodb.client.model.UpdateManyModel;
import com.mongodb.client.model.UpdateOneModel;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.model.WriteModel;
/**
* Default implementation for {@link BulkOperations}.
@@ -51,7 +56,9 @@ class DefaultBulkOperations implements BulkOperations {
private WriteConcernResolver writeConcernResolver;
private WriteConcern defaultWriteConcern;
private BulkWriteOperation bulk;
private BulkWriteOptions bulkOptions;
List<WriteModel<Document>> models = new ArrayList<WriteModel<Document>>();
/**
* Creates a new {@link DefaultBulkOperations} for the given {@link MongoOperations}, {@link BulkMode}, collection
@@ -77,7 +84,7 @@ class DefaultBulkOperations implements BulkOperations {
this.exceptionTranslator = new MongoExceptionTranslator();
this.writeConcernResolver = DefaultWriteConcernResolver.INSTANCE;
this.bulk = initBulkOperation();
this.bulkOptions = initBulkOperation();
}
/**
@@ -117,7 +124,7 @@ class DefaultBulkOperations implements BulkOperations {
Assert.notNull(document, "Document must not be null!");
bulk.insert((DBObject) mongoOperations.getConverter().convertToMongoType(document));
models.add(new InsertOneModel<Document>((Document) mongoOperations.getConverter().convertToMongoType(document)));
return this;
}
@@ -229,7 +236,8 @@ class DefaultBulkOperations implements BulkOperations {
Assert.notNull(query, "Query must not be null!");
bulk.find(query.getQueryObject()).remove();
models.add(new DeleteManyModel<Document>(query.getQueryObject()));
// bulk.find(query.getQueryObject()).remove();
return this;
}
@@ -255,15 +263,16 @@ class DefaultBulkOperations implements BulkOperations {
* @see org.springframework.data.mongodb.core.BulkOperations#executeBulk()
*/
@Override
public BulkWriteResult execute() {
MongoAction action = new MongoAction(defaultWriteConcern, MongoActionOperation.BULK, collectionName, entityType,
null, null);
WriteConcern writeConcern = writeConcernResolver.resolve(action);
public com.mongodb.bulk.BulkWriteResult execute() {
try {
return writeConcern == null ? bulk.execute() : bulk.execute(writeConcern);
MongoCollection<Document> collection = mongoOperations.getCollection(collectionName);
if (defaultWriteConcern != null) {
collection = collection.withWriteConcern(defaultWriteConcern);
}
return collection.bulkWrite(models, bulkOptions);
} catch (BulkWriteException o_O) {
@@ -271,7 +280,7 @@ class DefaultBulkOperations implements BulkOperations {
throw toThrow == null ? o_O : toThrow;
} finally {
this.bulk = initBulkOperation();
this.bulkOptions = initBulkOperation();
}
}
@@ -289,39 +298,26 @@ class DefaultBulkOperations implements BulkOperations {
Assert.notNull(query, "Query must not be null!");
Assert.notNull(update, "Update must not be null!");
BulkWriteRequestBuilder builder = bulk.find(query.getQueryObject());
if (upsert) {
UpdateOptions options = new UpdateOptions();
options.upsert(upsert);
if (multi) {
builder.upsert().update(update.getUpdateObject());
models.add(new UpdateManyModel<Document>(query.getQueryObject(), update.getUpdateObject(), options));
} else {
builder.upsert().updateOne(update.getUpdateObject());
models.add(new UpdateOneModel<Document>(query.getQueryObject(), update.getUpdateObject(), options));
}
} else {
if (multi) {
builder.update(update.getUpdateObject());
} else {
builder.updateOne(update.getUpdateObject());
}
}
return this;
}
private final BulkWriteOperation initBulkOperation() {
DBCollection collection = mongoOperations.getCollection(collectionName);
private final BulkWriteOptions initBulkOperation() {
BulkWriteOptions options = new BulkWriteOptions();
switch (bulkMode) {
case ORDERED:
return collection.initializeOrderedBulkOperation();
return options.ordered(true);
case UNORDERED:
return collection.initializeUnorderedBulkOperation();
return options.ordered(false);
}
throw new IllegalStateException("BulkMode was null!");
}
}

View File

@@ -21,16 +21,19 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.bson.Document;
import org.springframework.dao.DataAccessException;
import org.springframework.data.mongodb.core.index.IndexDefinition;
import org.springframework.data.mongodb.core.index.IndexField;
import org.springframework.data.mongodb.core.index.IndexInfo;
import org.springframework.util.Assert;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.IndexOptions;
/**
* Default implementation of {@link IndexOperations}.
@@ -70,10 +73,54 @@ public class DefaultIndexOperations implements IndexOperations {
*/
public void ensureIndex(final IndexDefinition indexDefinition) {
mongoOperations.execute(collectionName, new CollectionCallback<Object>() {
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
DBObject indexOptions = indexDefinition.getIndexOptions();
public Object doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
Document indexOptions = indexDefinition.getIndexOptions();
if (indexOptions != null) {
collection.createIndex(indexDefinition.getIndexKeys(), indexOptions);
IndexOptions ops = new IndexOptions();
if (indexOptions.containsKey("name")) {
ops = ops.name(indexOptions.get("name").toString());
}
if (indexOptions.containsKey("unique")) {
ops = ops.unique((Boolean) indexOptions.get("unique"));
}
// if(indexOptions.containsField("dropDuplicates")) {
// ops = ops.((boolean)indexOptions.get("dropDuplicates"));
// }
if (indexOptions.containsKey("sparse")) {
ops = ops.sparse((Boolean) indexOptions.get("sparse"));
}
if (indexOptions.containsKey("background")) {
ops = ops.background((Boolean) indexOptions.get("background"));
}
if (indexOptions.containsKey("expireAfterSeconds")) {
ops = ops.expireAfter((Long) indexOptions.get("expireAfterSeconds"), TimeUnit.SECONDS);
}
if (indexOptions.containsKey("min")) {
ops = ops.min(((Number) indexOptions.get("min")).doubleValue());
}
if (indexOptions.containsKey("max")) {
ops = ops.max(((Number) indexOptions.get("max")).doubleValue());
}
if (indexOptions.containsKey("bits")) {
ops = ops.bits((Integer) indexOptions.get("bits"));
}
if (indexOptions.containsKey("bucketSize")) {
ops = ops.bucketSize(((Number) indexOptions.get("bucketSize")).doubleValue());
}
if (indexOptions.containsKey("default_language")) {
ops = ops.defaultLanguage(indexOptions.get("default_language").toString());
}
if (indexOptions.containsKey("language_override")) {
ops = ops.languageOverride(indexOptions.get("language_override").toString());
}
if (indexOptions.containsKey("weights")) {
ops = ops.weights((Document) indexOptions.get("weights"));
}
collection.createIndex(indexDefinition.getIndexKeys(), ops);
} else {
collection.createIndex(indexDefinition.getIndexKeys());
}
@@ -88,7 +135,7 @@ public class DefaultIndexOperations implements IndexOperations {
*/
public void dropIndex(final String name) {
mongoOperations.execute(collectionName, new CollectionCallback<Void>() {
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
public Void doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
collection.dropIndex(name);
return null;
}
@@ -111,9 +158,10 @@ public class DefaultIndexOperations implements IndexOperations {
@Deprecated
public void resetIndexCache() {
mongoOperations.execute(collectionName, new CollectionCallback<Void>() {
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
public Void doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
ReflectiveDBCollectionInvoker.resetIndexCache(collection);
// TODO remove this one
// ReflectiveDBCollectionInvoker.resetIndexCache(collection);
return null;
}
});
@@ -126,18 +174,21 @@ public class DefaultIndexOperations implements IndexOperations {
public List<IndexInfo> getIndexInfo() {
return mongoOperations.execute(collectionName, new CollectionCallback<List<IndexInfo>>() {
public List<IndexInfo> doInCollection(DBCollection collection) throws MongoException, DataAccessException {
List<DBObject> dbObjectList = collection.getIndexInfo();
public List<IndexInfo> doInCollection(MongoCollection<Document> collection)
throws MongoException, DataAccessException {
MongoCursor<Document> dbObjectList = collection.listIndexes(Document.class).iterator();
return getIndexData(dbObjectList);
}
private List<IndexInfo> getIndexData(List<DBObject> dbObjectList) {
private List<IndexInfo> getIndexData(MongoCursor<Document> dbObjectList) {
List<IndexInfo> indexInfoList = new ArrayList<IndexInfo>();
for (DBObject ix : dbObjectList) {
while (dbObjectList.hasNext()) {
DBObject keyDbObject = (DBObject) ix.get("key");
Document ix = dbObjectList.next();
Document keyDbObject = (Document) ix.get("key");
int numberOfElements = keyDbObject.keySet().size();
List<IndexField> indexFields = new ArrayList<IndexField>(numberOfElements);
@@ -150,7 +201,7 @@ public class DefaultIndexOperations implements IndexOperations {
indexFields.add(IndexField.geo(key));
} else if ("text".equals(value)) {
DBObject weights = (DBObject) ix.get("weights");
Document weights = (Document) ix.get("weights");
for (String fieldName : weights.keySet()) {
indexFields.add(IndexField.text(fieldName, Float.valueOf(weights.get(fieldName).toString())));
}
@@ -169,10 +220,10 @@ public class DefaultIndexOperations implements IndexOperations {
String name = ix.get("name").toString();
boolean unique = ix.containsField("unique") ? (Boolean) ix.get("unique") : false;
boolean dropDuplicates = ix.containsField("dropDups") ? (Boolean) ix.get("dropDups") : false;
boolean sparse = ix.containsField("sparse") ? (Boolean) ix.get("sparse") : false;
String language = ix.containsField("default_language") ? (String) ix.get("default_language") : "";
boolean unique = ix.containsKey("unique") ? (Boolean) ix.get("unique") : false;
boolean dropDuplicates = ix.containsKey("dropDups") ? (Boolean) ix.get("dropDups") : false;
boolean sparse = ix.containsKey("sparse") ? (Boolean) ix.get("sparse") : false;
String language = ix.containsKey("default_language") ? (String) ix.get("default_language") : "";
indexInfoList.add(new IndexInfo(indexFields, name, unique, dropDuplicates, sparse, language));
}

View File

@@ -20,11 +20,13 @@ import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.dao.DataAccessException;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
@@ -34,8 +36,9 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.mongodb.DB;
import com.mongodb.BasicDBList;
import com.mongodb.MongoException;
import com.mongodb.client.MongoDatabase;
/**
* Default implementation of {@link ScriptOperations} capable of saving and executing {@link ServerSideJavaScript}.
@@ -97,8 +100,13 @@ class DefaultScriptOperations implements ScriptOperations {
return mongoOperations.execute(new DbCallback<Object>() {
@Override
public Object doInDB(DB db) throws MongoException, DataAccessException {
return db.eval(script.getCode(), convertScriptArgs(false, args));
public Object doInDB(MongoDatabase db) throws MongoException, DataAccessException {
Document command = new Document("$eval", script.getCode());
BasicDBList commandArgs = new BasicDBList();
commandArgs.addAll(Arrays.asList(convertScriptArgs(false, args)));
command.append("args", commandArgs);
return db.runCommand(command).get("retval");
}
});
}
@@ -115,8 +123,10 @@ class DefaultScriptOperations implements ScriptOperations {
return mongoOperations.execute(new DbCallback<Object>() {
@Override
public Object doInDB(DB db) throws MongoException, DataAccessException {
return db.eval(String.format("%s(%s)", scriptName, convertAndJoinScriptArgs(args)));
public Object doInDB(MongoDatabase db) throws MongoException, DataAccessException {
return db.runCommand(new Document("eval", String.format("%s(%s)", scriptName, convertAndJoinScriptArgs(args))))
.get("retval");
}
});
}

View File

@@ -15,24 +15,21 @@
*/
package org.springframework.data.mongodb.core;
import org.bson.Document;
import org.springframework.dao.DataAccessException;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
/**
* An interface used by {@link MongoTemplate} for processing documents returned from a MongoDB query on a per-document
* basis. Implementations of this interface perform the actual work of prcoessing each document but don't need to worry
* about exception handling. {@MongoException}s will be caught and translated by the calling
* MongoTemplate
*
* An DocumentCallbackHandler is typically stateful: It keeps the result state within the object, to be available later
* for later inspection.
* about exception handling. {@MongoException}s will be caught and translated by the calling MongoTemplate An
* DocumentCallbackHandler is typically stateful: It keeps the result state within the object, to be available later for
* later inspection.
*
* @author Mark Pollack
*
*/
public interface DocumentCallbackHandler {
void processDocument(DBObject dbObject) throws MongoException, DataAccessException;
void processDocument(Document dbObject) throws MongoException, DataAccessException;
}

View File

@@ -15,11 +15,9 @@
*/
package org.springframework.data.mongodb.core;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Value object to mitigate different representations of geo command execution results in MongoDB.
*
@@ -28,16 +26,16 @@ import com.mongodb.DBObject;
*/
class GeoCommandStatistics {
private static final GeoCommandStatistics NONE = new GeoCommandStatistics(new BasicDBObject());
private static final GeoCommandStatistics NONE = new GeoCommandStatistics(new Document());
private final DBObject source;
private final Document source;
/**
* Creates a new {@link GeoCommandStatistics} instance with the given source document.
*
* @param source must not be {@literal null}.
*/
private GeoCommandStatistics(DBObject source) {
private GeoCommandStatistics(Document source) {
Assert.notNull(source, "Source document must not be null!");
this.source = source;
@@ -49,12 +47,12 @@ class GeoCommandStatistics {
* @param commandResult must not be {@literal null}.
* @return
*/
public static GeoCommandStatistics from(DBObject commandResult) {
public static GeoCommandStatistics from(Document commandResult) {
Assert.notNull(commandResult, "Command result must not be null!");
Object stats = commandResult.get("stats");
return stats == null ? NONE : new GeoCommandStatistics((DBObject) stats);
return stats == null ? NONE : new GeoCommandStatistics((Document) stats);
}
/**

View File

@@ -15,9 +15,9 @@
*/
package org.springframework.data.mongodb.core;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.DBObject;
import com.mongodb.WriteConcern;
/**
@@ -38,8 +38,8 @@ public class MongoAction {
private final WriteConcern defaultWriteConcern;
private final Class<?> entityType;
private final MongoActionOperation mongoActionOperation;
private final DBObject query;
private final DBObject document;
private final Document query;
private final Document document;
/**
* Create an instance of a {@link MongoAction}.
@@ -48,11 +48,11 @@ public class MongoAction {
* @param mongoActionOperation action being taken against the collection
* @param collectionName the collection name, must not be {@literal null} or empty.
* @param entityType the POJO that is being operated against
* @param document the converted DBObject from the POJO or Spring Update object
* @param query the converted DBObject from the Spring Query object
* @param document the converted Document from the POJO or Spring Update object
* @param query the converted Document from the Spring Query object
*/
public MongoAction(WriteConcern defaultWriteConcern, MongoActionOperation mongoActionOperation,
String collectionName, Class<?> entityType, DBObject document, DBObject query) {
public MongoAction(WriteConcern defaultWriteConcern, MongoActionOperation mongoActionOperation, String collectionName,
Class<?> entityType, Document document, Document query) {
Assert.hasText(collectionName, "Collection name must not be null or empty!");
@@ -88,11 +88,11 @@ public class MongoAction {
return mongoActionOperation;
}
public DBObject getQuery() {
public Document getQuery() {
return query;
}
public DBObject getDocument() {
public Document getDocument() {
return document;
}

View File

@@ -19,6 +19,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.bson.BsonInvalidOperationException;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.DataIntegrityViolationException;
@@ -33,7 +34,10 @@ import org.springframework.data.mongodb.util.MongoDbErrorCodes;
import org.springframework.util.ClassUtils;
import com.mongodb.BulkWriteException;
import com.mongodb.MongoBulkWriteException;
import com.mongodb.MongoException;
import com.mongodb.MongoServerException;
import com.mongodb.bulk.BulkWriteError;
/**
* Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate
@@ -57,7 +61,7 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
Arrays.asList("MongoInternalException"));
private static final Set<String> DATA_INTEGRETY_EXCEPTIONS = new HashSet<String>(
Arrays.asList("WriteConcernException"));
Arrays.asList("WriteConcernException", "MongoWriteException", "MongoBulkWriteException"));
/*
* (non-Javadoc)
@@ -67,6 +71,10 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
// Check for well-known MongoException subclasses.
if (ex instanceof BsonInvalidOperationException) {
throw new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
}
String exception = ClassUtils.getShortName(ClassUtils.getUserClass(ex.getClass()));
if (DULICATE_KEY_EXCEPTIONS.contains(exception)) {
@@ -82,6 +90,20 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
}
if (DATA_INTEGRETY_EXCEPTIONS.contains(exception)) {
if (ex instanceof MongoServerException) {
if (((MongoServerException) ex).getCode() == 11000) {
return new DuplicateKeyException(ex.getMessage(), ex);
}
if (ex instanceof MongoBulkWriteException) {
for (BulkWriteError x : ((MongoBulkWriteException) ex).getWriteErrors()) {
if (x.getCode() == 11000) {
return new DuplicateKeyException(ex.getMessage(), ex);
}
}
}
}
return new DataIntegrityViolationException(ex.getMessage(), ex);
}

View File

@@ -19,6 +19,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.bson.Document;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
@@ -36,13 +37,12 @@ import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.CloseableIterator;
import com.mongodb.CommandResult;
import com.mongodb.Cursor;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.ReadPreference;
import com.mongodb.WriteResult;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
/**
* Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}. Not often used but
@@ -69,12 +69,12 @@ public interface MongoOperations {
/**
* Execute the a MongoDB command expressed as a JSON string. This will call the method JSON.parse that is part of the
* MongoDB driver to convert the JSON string to a DBObject. Any errors that result from executing this command will be
* MongoDB driver to convert the JSON string to a Document. Any errors that result from executing this command will be
* converted into Spring's DAO exception hierarchy.
*
* @param jsonCommand a MongoDB command expressed as a JSON string.
*/
CommandResult executeCommand(String jsonCommand);
Document executeCommand(String jsonCommand);
/**
* Execute a MongoDB command. Any errors that result from executing this command will be converted into Spring's DAO
@@ -82,7 +82,7 @@ public interface MongoOperations {
*
* @param command a MongoDB command
*/
CommandResult executeCommand(DBObject command);
Document executeCommand(Document command);
/**
* Execute a MongoDB command. Any errors that result from executing this command will be converted into Spring's DAO
@@ -90,11 +90,11 @@ public interface MongoOperations {
*
* @param command a MongoDB command
* @param options query options to use
* @deprecated since 1.7. Please use {@link #executeCommand(DBObject, ReadPreference)}, as the MongoDB Java driver
* @deprecated since 1.7. Please use {@link #executeCommand(Document, ReadPreference)}, as the MongoDB Java driver
* version 3 no longer supports this operation.
*/
@Deprecated
CommandResult executeCommand(DBObject command, int options);
Document executeCommand(Document command, int options);
/**
* Execute a MongoDB command. Any errors that result from executing this command will be converted into Spring's data
@@ -105,7 +105,7 @@ public interface MongoOperations {
* @return
* @since 1.7
*/
CommandResult executeCommand(DBObject command, ReadPreference readPreference);
Document executeCommand(Document command, ReadPreference readPreference);
/**
* Execute a MongoDB query and iterate over the query results on a per-document basis with a DocumentCallbackHandler.
@@ -203,7 +203,7 @@ public interface MongoOperations {
* @param entityClass class that determines the collection to create
* @return the created collection
*/
<T> DBCollection createCollection(Class<T> entityClass);
<T> MongoCollection<Document> createCollection(Class<T> entityClass);
/**
* Create a collection with a name based on the provided entity class using the options.
@@ -212,7 +212,7 @@ public interface MongoOperations {
* @param collectionOptions options to use when creating the collection.
* @return the created collection
*/
<T> DBCollection createCollection(Class<T> entityClass, CollectionOptions collectionOptions);
<T> MongoCollection<Document> createCollection(Class<T> entityClass, CollectionOptions collectionOptions);
/**
* Create an uncapped collection with the provided name.
@@ -220,7 +220,7 @@ public interface MongoOperations {
* @param collectionName name of the collection
* @return the created collection
*/
DBCollection createCollection(String collectionName);
MongoCollection<Document> createCollection(String collectionName);
/**
* Create a collection with the provided name and options.
@@ -229,7 +229,7 @@ public interface MongoOperations {
* @param collectionOptions options to use when creating the collection.
* @return the created collection
*/
DBCollection createCollection(String collectionName, CollectionOptions collectionOptions);
MongoCollection<Document> createCollection(String collectionName, CollectionOptions collectionOptions);
/**
* A set of collection names.
@@ -246,7 +246,7 @@ public interface MongoOperations {
* @param collectionName name of the collection
* @return an existing collection or a newly created one.
*/
DBCollection getCollection(String collectionName);
MongoCollection<Document> getCollection(String collectionName);
/**
* Check to see if a collection with a name indicated by the entity class exists.
@@ -864,7 +864,7 @@ public interface MongoOperations {
* @param entityClass class that determines the collection to use
* @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult upsert(Query query, Update update, Class<?> entityClass);
UpdateResult upsert(Query query, Update update, Class<?> entityClass);
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
@@ -876,7 +876,7 @@ public interface MongoOperations {
* @param collectionName name of the collection to update the object in
* @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult upsert(Query query, Update update, String collectionName);
UpdateResult upsert(Query query, Update update, String collectionName);
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
@@ -888,7 +888,7 @@ public interface MongoOperations {
* @param collectionName name of the collection to update the object in
* @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult upsert(Query query, Update update, Class<?> entityClass, String collectionName);
UpdateResult upsert(Query query, Update update, Class<?> entityClass, String collectionName);
/**
* Updates the first object that is found in the collection of the entity class that matches the query document with
@@ -900,7 +900,7 @@ public interface MongoOperations {
* @param entityClass class that determines the collection to use
* @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateFirst(Query query, Update update, Class<?> entityClass);
UpdateResult updateFirst(Query query, Update update, Class<?> entityClass);
/**
* Updates the first object that is found in the specified collection that matches the query document criteria with
@@ -912,7 +912,7 @@ public interface MongoOperations {
* @param collectionName name of the collection to update the object in
* @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateFirst(Query query, Update update, String collectionName);
UpdateResult updateFirst(Query query, Update update, String collectionName);
/**
* Updates the first object that is found in the specified collection that matches the query document criteria with
@@ -925,7 +925,7 @@ public interface MongoOperations {
* @param collectionName name of the collection to update the object in
* @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateFirst(Query query, Update update, Class<?> entityClass, String collectionName);
UpdateResult updateFirst(Query query, Update update, Class<?> entityClass, String collectionName);
/**
* Updates all objects that are found in the collection for the entity class that matches the query document criteria
@@ -937,7 +937,7 @@ public interface MongoOperations {
* @param entityClass class that determines the collection to use
* @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateMulti(Query query, Update update, Class<?> entityClass);
UpdateResult updateMulti(Query query, Update update, Class<?> entityClass);
/**
* Updates all objects that are found in the specified collection that matches the query document criteria with the
@@ -949,7 +949,7 @@ public interface MongoOperations {
* @param collectionName name of the collection to update the object in
* @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateMulti(Query query, Update update, String collectionName);
UpdateResult updateMulti(Query query, Update update, String collectionName);
/**
* Updates all objects that are found in the collection for the entity class that matches the query document criteria
@@ -962,14 +962,14 @@ public interface MongoOperations {
* @param collectionName name of the collection to update the object in
* @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateMulti(final Query query, final Update update, Class<?> entityClass, String collectionName);
UpdateResult updateMulti(final Query query, final Update update, Class<?> entityClass, String collectionName);
/**
* Remove the given object from the collection by id.
*
* @param object
*/
WriteResult remove(Object object);
DeleteResult remove(Object object);
/**
* Removes the given object from the given collection.
@@ -977,7 +977,7 @@ public interface MongoOperations {
* @param object
* @param collection must not be {@literal null} or empty.
*/
WriteResult remove(Object object, String collection);
DeleteResult remove(Object object, String collection);
/**
* Remove all documents that match the provided query document criteria from the the collection used to store the
@@ -986,7 +986,7 @@ public interface MongoOperations {
* @param query
* @param entityClass
*/
WriteResult remove(Query query, Class<?> entityClass);
DeleteResult remove(Query query, Class<?> entityClass);
/**
* Remove all documents that match the provided query document criteria from the the collection used to store the
@@ -996,7 +996,7 @@ public interface MongoOperations {
* @param entityClass
* @param collectionName
*/
WriteResult remove(Query query, Class<?> entityClass, String collectionName);
DeleteResult remove(Query query, Class<?> entityClass, String collectionName);
/**
* Remove all documents from the specified collection that match the provided query document criteria. There is no
@@ -1005,7 +1005,7 @@ public interface MongoOperations {
* @param query the query document that specifies the criteria used to remove a record
* @param collectionName name of the collection where the objects will removed
*/
WriteResult remove(Query query, String collectionName);
DeleteResult remove(Query query, String collectionName);
/**
* Returns and removes all documents form the specified collection that match the provided query.

View File

@@ -20,10 +20,10 @@ import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.bson.Document;
import org.springframework.data.mongodb.util.MongoClientVersion;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
/**
* {@link ReflectiveDBCollectionInvoker} provides reflective access to {@link DBCollection} API that is not consistently
@@ -40,7 +40,7 @@ class ReflectiveDBCollectionInvoker {
static {
GEN_INDEX_NAME_METHOD = findMethod(DBCollection.class, "genIndexName", DBObject.class);
GEN_INDEX_NAME_METHOD = findMethod(DBCollection.class, "genIndexName", Document.class);
RESET_INDEX_CHACHE_METHOD = findMethod(DBCollection.class, "resetIndexCache");
}
@@ -53,7 +53,7 @@ class ReflectiveDBCollectionInvoker {
* @param keys the names of the fields used in this index
* @return
*/
public static String generateIndexName(DBObject keys) {
public static String generateIndexName(Document keys) {
if (isMongo3Driver()) {
return genIndexName(keys);
@@ -79,14 +79,14 @@ class ReflectiveDBCollectionInvoker {
}
/**
* Borrowed from MongoDB Java driver version 2. See <a
* href="http://github.com/mongodb/mongo-java-driver/blob/r2.13.0/src/main/com/mongodb/DBCollection.java#L754"
* >http://github.com/mongodb/mongo-java-driver/blob/r2.13.0/src/main/com/mongodb/DBCollection.java#L754</a>
* Borrowed from MongoDB Java driver version 2. See
* <a href="http://github.com/mongodb/mongo-java-driver/blob/r2.13.0/src/main/com/mongodb/DBCollection.java#L754" >
* http://github.com/mongodb/mongo-java-driver/blob/r2.13.0/src/main/com/mongodb/DBCollection.java#L754</a>
*
* @param keys
* @return
*/
private static String genIndexName(DBObject keys) {
private static String genIndexName(Document keys) {
StringBuilder name = new StringBuilder();

View File

@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import com.mongodb.MongoException;
import com.mongodb.WriteResult;
import com.mongodb.client.result.UpdateResult;
/**
* {@link ReflectiveWriteResultInvoker} provides reflective access to {@link WriteResult} API that is not consistently
@@ -35,6 +36,7 @@ final class ReflectiveWriteResultInvoker {
private static final Method GET_ERROR_METHOD;
private static final Method WAS_ACKNOWLEDGED_METHOD;
private static final Method WAS_ACKNOWLEDGED_METHOD_UR;
private ReflectiveWriteResultInvoker() {}
@@ -42,6 +44,7 @@ final class ReflectiveWriteResultInvoker {
GET_ERROR_METHOD = findMethod(WriteResult.class, "getError");
WAS_ACKNOWLEDGED_METHOD = findMethod(WriteResult.class, "wasAcknowledged");
WAS_ACKNOWLEDGED_METHOD_UR = findMethod(UpdateResult.class, "wasAcknowledged");
}
/**
@@ -64,4 +67,12 @@ final class ReflectiveWriteResultInvoker {
public static boolean wasAcknowledged(WriteResult writeResult) {
return isMongo3Driver() ? ((Boolean) invokeMethod(WAS_ACKNOWLEDGED_METHOD, writeResult)).booleanValue() : true;
}
/**
* @param writeResult
* @return return in case of MongoDB Java driver version 2.
*/
public static boolean wasAcknowledged(UpdateResult writeResult) {
return isMongo3Driver() ? ((Boolean) invokeMethod(WAS_ACKNOWLEDGED_METHOD_UR, writeResult)).booleanValue() : true;
}
}

View File

@@ -33,6 +33,7 @@ import com.mongodb.MongoClientURI;
import com.mongodb.MongoException;
import com.mongodb.MongoURI;
import com.mongodb.WriteConcern;
import com.mongodb.client.MongoDatabase;
/**
* Factory to create {@link DB} instances from a {@link Mongo} instance.
@@ -187,7 +188,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
* (non-Javadoc)
* @see org.springframework.data.mongodb.MongoDbFactory#getDb()
*/
public DB getDb() throws DataAccessException {
public MongoDatabase getDb() throws DataAccessException {
return getDb(databaseName);
}
@@ -195,18 +196,17 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
* (non-Javadoc)
* @see org.springframework.data.mongodb.MongoDbFactory#getDb(java.lang.String)
*/
@SuppressWarnings("deprecation")
public DB getDb(String dbName) throws DataAccessException {
public MongoDatabase getDb(String dbName) throws DataAccessException {
Assert.hasText(dbName, "Database name must not be empty.");
DB db = MongoDbUtils.getDB(mongo, dbName, credentials, authenticationDatabaseName);
MongoDatabase db = ((MongoClient) mongo).getDatabase(dbName);
if (writeConcern != null) {
db.setWriteConcern(writeConcern);
if (writeConcern == null) {
return db;
}
return db;
return db.withWriteConcern(writeConcern);
}
/**
@@ -232,4 +232,10 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
public PersistenceExceptionTranslator getExceptionTranslator() {
return this.exceptionTranslator;
}
@SuppressWarnings("deprecation")
@Override
public DB getLegacyDb() {
return mongo.getDB(databaseName);
}
}

View File

@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bson.Document;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
@@ -32,9 +33,6 @@ import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.SerializationUtils;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* An {@code Aggregation} is a representation of a list of aggregation steps to be performed by the MongoDB Aggregation
* Framework.
@@ -491,19 +489,19 @@ public class Aggregation {
}
/**
* Converts this {@link Aggregation} specification to a {@link DBObject}.
* Converts this {@link Aggregation} specification to a {@link Document}.
*
* @param inputCollectionName the name of the input collection
* @return the {@code DBObject} representing this aggregation
* @return the {@code Document} representing this aggregation
*/
public DBObject toDbObject(String inputCollectionName, AggregationOperationContext rootContext) {
public Document toDbObject(String inputCollectionName, AggregationOperationContext rootContext) {
AggregationOperationContext context = rootContext;
List<DBObject> operationDocuments = new ArrayList<DBObject>(operations.size());
List<Document> operationDocuments = new ArrayList<Document>(operations.size());
for (AggregationOperation operation : operations) {
operationDocuments.add(operation.toDBObject(context));
operationDocuments.add(operation.toDocument(context));
if (operation instanceof FieldsExposingAggregationOperation) {
@@ -517,7 +515,7 @@ public class Aggregation {
}
}
DBObject command = new BasicDBObject("aggregate", inputCollectionName);
Document command = new Document("aggregate", inputCollectionName);
command.put("pipeline", operationDocuments);
command = options.applyAndReturnPotentiallyChangedCommand(command);
@@ -544,10 +542,10 @@ public class Aggregation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperationContext#getMappedObject(com.mongodb.DBObject)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperationContext#getMappedObject(com.mongodb.Document)
*/
@Override
public DBObject getMappedObject(DBObject dbObject) {
public Document getMappedObject(Document dbObject) {
return dbObject;
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* An {@link AggregationExpression} can be used with field expressions in aggregation pipeline stages like
@@ -28,11 +28,11 @@ import com.mongodb.DBObject;
public interface AggregationExpression {
/**
* Turns the {@link AggregationExpression} into a {@link DBObject} within the given
* Turns the {@link AggregationExpression} into a {@link Document} within the given
* {@link AggregationOperationContext}.
*
* @param context
* @return
*/
DBObject toDbObject(AggregationOperationContext context);
Document toDbObject(AggregationOperationContext context);
}

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.AggregationExpressionTransformer.AggregationExpressionTransformationContext;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference;
import org.springframework.data.mongodb.core.spel.ExpressionNode;
@@ -22,16 +23,14 @@ import org.springframework.data.mongodb.core.spel.ExpressionTransformationContex
import org.springframework.data.mongodb.core.spel.ExpressionTransformer;
import org.springframework.util.Assert;
import com.mongodb.DBObject;
/**
* Interface to type an {@link ExpressionTransformer} to the contained
* {@link AggregationExpressionTransformationContext}.
*
* @author Oliver Gierke
*/
interface AggregationExpressionTransformer extends
ExpressionTransformer<AggregationExpressionTransformationContext<ExpressionNode>> {
interface AggregationExpressionTransformer
extends ExpressionTransformer<AggregationExpressionTransformationContext<ExpressionNode>> {
/**
* A special {@link ExpressionTransformationContextSupport} to be aware of the {@link AggregationOperationContext}.
@@ -39,8 +38,8 @@ interface AggregationExpressionTransformer extends
* @author Oliver Gierke
* @author Thomas Darimont
*/
public static class AggregationExpressionTransformationContext<T extends ExpressionNode> extends
ExpressionTransformationContextSupport<T> {
public static class AggregationExpressionTransformationContext<T extends ExpressionNode>
extends ExpressionTransformationContextSupport<T> {
private final AggregationOperationContext aggregationContext;
@@ -53,7 +52,7 @@ interface AggregationExpressionTransformer extends
* @param aggregationContext must not be {@literal null}.
*/
public AggregationExpressionTransformationContext(T currentNode, ExpressionNode parentNode,
DBObject previousOperationObject, AggregationOperationContext context) {
Document previousOperationObject, AggregationOperationContext context) {
super(currentNode, parentNode, previousOperationObject);

View File

@@ -19,11 +19,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* An enum of supported {@link AggregationExpression}s in aggregation pipeline stages.
*
@@ -79,7 +77,7 @@ public enum AggregationFunctionExpressions {
* @see org.springframework.data.mongodb.core.aggregation.Expression#toDbObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDbObject(AggregationOperationContext context) {
public Document toDbObject(AggregationOperationContext context) {
List<Object> args = new ArrayList<Object>(values.size());
@@ -87,7 +85,7 @@ public enum AggregationFunctionExpressions {
args.add(unpack(value, context));
}
return new BasicDBObject("$" + name, args);
return new Document("$" + name, args);
}
private static Object unpack(Object value, AggregationOperationContext context) {

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* Represents one single operation in an aggregation pipeline.
@@ -28,10 +28,10 @@ import com.mongodb.DBObject;
public interface AggregationOperation {
/**
* Turns the {@link AggregationOperation} into a {@link DBObject} by using the given
* Turns the {@link AggregationOperation} into a {@link Document} by using the given
* {@link AggregationOperationContext}.
*
* @return the DBObject
* @return the Document
*/
DBObject toDBObject(AggregationOperationContext context);
Document toDocument(AggregationOperationContext context);
}

View File

@@ -15,10 +15,9 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference;
import com.mongodb.DBObject;
/**
* The context for an {@link AggregationOperation}.
*
@@ -28,12 +27,12 @@ import com.mongodb.DBObject;
public interface AggregationOperationContext {
/**
* Returns the mapped {@link DBObject}, potentially converting the source considering mapping metadata etc.
* Returns the mapped {@link Document}, potentially converting the source considering mapping metadata etc.
*
* @param dbObject will never be {@literal null}.
* @return must not be {@literal null}.
*/
DBObject getMappedObject(DBObject dbObject);
Document getMappedObject(Document dbObject);
/**
* Returns a {@link FieldReference} for the given field or {@literal null} if the context does not expose the given

View File

@@ -15,8 +15,7 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* Holds a set of configurable aggregation options that can be used within an aggregation pipeline. A list of support
@@ -37,7 +36,7 @@ public class AggregationOptions {
private final boolean allowDiskUse;
private final boolean explain;
private final DBObject cursor;
private final Document cursor;
/**
* Creates a new {@link AggregationOptions}.
@@ -46,7 +45,7 @@ public class AggregationOptions {
* @param explain whether to get the execution plan for the aggregation instead of the actual results.
* @param cursor can be {@literal null}, used to pass additional options to the aggregation.
*/
public AggregationOptions(boolean allowDiskUse, boolean explain, DBObject cursor) {
public AggregationOptions(boolean allowDiskUse, boolean explain, Document cursor) {
this.allowDiskUse = allowDiskUse;
this.explain = explain;
@@ -77,7 +76,7 @@ public class AggregationOptions {
*
* @return
*/
public DBObject getCursor() {
public Document getCursor() {
return cursor;
}
@@ -88,19 +87,19 @@ public class AggregationOptions {
* @param command the aggregation command.
* @return
*/
DBObject applyAndReturnPotentiallyChangedCommand(DBObject command) {
Document applyAndReturnPotentiallyChangedCommand(Document command) {
DBObject result = new BasicDBObject(command.toMap());
Document result = new Document(command);
if (allowDiskUse && !result.containsField(ALLOW_DISK_USE)) {
if (allowDiskUse && !result.containsKey(ALLOW_DISK_USE)) {
result.put(ALLOW_DISK_USE, allowDiskUse);
}
if (explain && !result.containsField(EXPLAIN)) {
if (explain && !result.containsKey(EXPLAIN)) {
result.put(EXPLAIN, explain);
}
if (cursor != null && !result.containsField(CURSOR)) {
if (cursor != null && !result.containsKey(CURSOR)) {
result.put("cursor", cursor);
}
@@ -108,13 +107,13 @@ public class AggregationOptions {
}
/**
* Returns a {@link DBObject} representation of this {@link AggregationOptions}.
* Returns a {@link Document} representation of this {@link AggregationOptions}.
*
* @return
*/
public DBObject toDbObject() {
public Document toDbObject() {
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
dbo.put(ALLOW_DISK_USE, allowDiskUse);
dbo.put(EXPLAIN, explain);
dbo.put(CURSOR, cursor);
@@ -127,7 +126,7 @@ public class AggregationOptions {
*/
@Override
public String toString() {
return toDbObject().toString();
return toDbObject().toJson();
}
/**
@@ -139,7 +138,7 @@ public class AggregationOptions {
private boolean allowDiskUse;
private boolean explain;
private DBObject cursor;
private Document cursor;
/**
* Defines whether to off-load intensive sort-operations to disk.
@@ -171,7 +170,7 @@ public class AggregationOptions {
* @param cursor
* @return
*/
public Builder cursor(DBObject cursor) {
public Builder cursor(Document cursor) {
this.cursor = cursor;
return this;

View File

@@ -19,10 +19,9 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.DBObject;
/**
* Collects the results of executing an aggregation operation.
*
@@ -35,7 +34,7 @@ import com.mongodb.DBObject;
public class AggregationResults<T> implements Iterable<T> {
private final List<T> mappedResults;
private final DBObject rawResults;
private final Document rawResults;
private final String serverUsed;
/**
@@ -44,7 +43,7 @@ public class AggregationResults<T> implements Iterable<T> {
* @param mappedResults must not be {@literal null}.
* @param rawResults must not be {@literal null}.
*/
public AggregationResults(List<T> mappedResults, DBObject rawResults) {
public AggregationResults(List<T> mappedResults, Document rawResults) {
Assert.notNull(mappedResults);
Assert.notNull(rawResults);
@@ -97,7 +96,7 @@ public class AggregationResults<T> implements Iterable<T> {
* @return
* @since 1.6
*/
public DBObject getRawResults() {
public Document getRawResults() {
return rawResults;
}

View File

@@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core.aggregation;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.util.Assert;
@@ -98,15 +99,15 @@ public class ConditionalOperator implements AggregationExpression {
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDbObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDbObject(AggregationOperationContext context) {
public Document toDbObject(AggregationOperationContext context) {
BasicDBObject condObject = new BasicDBObject();
Document condObject = new Document();
condObject.append("if", resolveCriteria(context, condition));
condObject.append("then", resolveValue(context, thenValue));
condObject.append("else", resolveValue(context, otherwiseValue));
return new BasicDBObject("$cond", condObject);
return new Document("$cond", condObject);
}
private Object resolveValue(AggregationOperationContext context, Object value) {
@@ -119,7 +120,7 @@ public class ConditionalOperator implements AggregationExpression {
return ((ConditionalOperator) value).toDbObject(context);
}
return context.getMappedObject(new BasicDBObject("$set", value)).get("$set");
return context.getMappedObject(new Document("$set", value)).get("$set");
}
private Object resolveCriteria(AggregationOperationContext context, Object value) {
@@ -130,7 +131,7 @@ public class ConditionalOperator implements AggregationExpression {
if (value instanceof CriteriaDefinition) {
DBObject mappedObject = context.getMappedObject(((CriteriaDefinition) value).getCriteriaObject());
Document mappedObject = context.getMappedObject(((CriteriaDefinition) value).getCriteriaObject());
List<Object> clauses = new ArrayList<Object>();
clauses.addAll(getClauses(context, mappedObject));
@@ -146,7 +147,7 @@ public class ConditionalOperator implements AggregationExpression {
String.format("Invalid value in condition. Supported: DBObject, Field references, Criteria, got: %s", value));
}
private List<Object> getClauses(AggregationOperationContext context, DBObject mappedObject) {
private List<Object> getClauses(AggregationOperationContext context, Document mappedObject) {
List<Object> clauses = new ArrayList<Object>();
@@ -167,16 +168,16 @@ public class ConditionalOperator implements AggregationExpression {
List<Object> args = new ArrayList<Object>();
for (Object clause : (List<?>) predicate) {
if (clause instanceof DBObject) {
args.addAll(getClauses(context, (DBObject) clause));
if (clause instanceof Document) {
args.addAll(getClauses(context, (Document) clause));
}
}
clauses.add(new BasicDBObject(key, args));
} else if (predicate instanceof DBObject) {
} else if (predicate instanceof Document) {
DBObject nested = (DBObject) predicate;
Document nested = (Document) predicate;
for (String s : nested.keySet()) {
@@ -213,8 +214,8 @@ public class ConditionalOperator implements AggregationExpression {
private Object resolve(AggregationOperationContext context, Object value) {
if (value instanceof DBObject) {
return context.getMappedObject((DBObject) value);
if (value instanceof Document) {
return context.getMappedObject((Document) value);
}
return context.getReference((Field) value).toString();

View File

@@ -15,12 +15,11 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference;
import org.springframework.util.Assert;
import com.mongodb.DBObject;
/**
* {@link AggregationOperationContext} that combines the available field references from a given
* {@code AggregationOperationContext} and an {@link FieldsExposingAggregationOperation}.
@@ -54,10 +53,10 @@ class ExposedFieldsAggregationOperationContext implements AggregationOperationCo
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperationContext#getMappedObject(com.mongodb.DBObject)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperationContext#getMappedObject(com.mongodb.Document)
*/
@Override
public DBObject getMappedObject(DBObject dbObject) {
public Document getMappedObject(Document dbObject) {
return rootContext.getMappedObject(dbObject);
}

View File

@@ -15,12 +15,10 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Represents a {@code geoNear} aggregation operation.
* <p>
@@ -53,14 +51,14 @@ public class GeoNearOperation implements AggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
public Document toDocument(AggregationOperationContext context) {
BasicDBObject command = (BasicDBObject) context.getMappedObject(nearQuery.toDBObject());
Document command = context.getMappedObject(nearQuery.toDocument());
command.put("distanceField", distanceField);
return new BasicDBObject("$geoNear", command);
return new Document("$geoNear", command);
}
}

View File

@@ -21,14 +21,12 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Encapsulates the aggregation framework {@code $group}-operation.
* <p>
@@ -194,7 +192,8 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $last}-expression for the given {@link AggregationExpression}.
* Generates an {@link GroupOperationBuilder} for an {@code $last}-expression for the given
* {@link AggregationExpression}.
*
* @param expr
* @return
@@ -214,7 +213,8 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
}
/**
* Generates an {@link GroupOperationBuilder} for a {@code $first}-expression for the given {@link AggregationExpression}.
* Generates an {@link GroupOperationBuilder} for a {@code $first}-expression for the given
* {@link AggregationExpression}.
*
* @param expr
* @return
@@ -234,7 +234,8 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $avg}-expression for the given {@link AggregationExpression}.
* Generates an {@link GroupOperationBuilder} for an {@code $avg}-expression for the given
* {@link AggregationExpression}.
*
* @param expr
* @return
@@ -278,7 +279,8 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $min}-expression that for the given {@link AggregationExpression}.
* Generates an {@link GroupOperationBuilder} for an {@code $min}-expression that for the given
* {@link AggregationExpression}.
*
* @param expr
* @return
@@ -298,7 +300,8 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $max}-expression that for the given {@link AggregationExpression}.
* Generates an {@link GroupOperationBuilder} for an {@code $max}-expression that for the given
* {@link AggregationExpression}.
*
* @param expr
* @return
@@ -329,12 +332,12 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public com.mongodb.DBObject toDBObject(AggregationOperationContext context) {
public Document toDocument(AggregationOperationContext context) {
BasicDBObject operationObject = new BasicDBObject();
Document operationObject = new Document();
if (idFields.exposesNoNonSyntheticFields()) {
@@ -347,7 +350,7 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
} else {
BasicDBObject inner = new BasicDBObject();
Document inner = new Document();
for (ExposedField field : idFields) {
FieldReference reference = context.getReference(field);
@@ -358,10 +361,10 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
}
for (Operation operation : operations) {
operationObject.putAll(operation.toDBObject(context));
operationObject.putAll(operation.toDocument(context));
}
return new BasicDBObject("$group", operationObject);
return new Document("$group", operationObject);
}
interface Keyword {
@@ -412,8 +415,8 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
return new ExposedField(key, true);
}
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject(key, new BasicDBObject(op.toString(), getValue(context)));
public Document toDocument(AggregationOperationContext context) {
return new Document(key, new Document(op.toString(), getValue(context)));
}
public Object getValue(AggregationOperationContext context) {

View File

@@ -19,6 +19,7 @@ package org.springframework.data.mongodb.core.aggregation;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
@@ -57,14 +58,14 @@ public class IfNullOperator implements AggregationExpression {
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDbObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDbObject(AggregationOperationContext context) {
public Document toDbObject(AggregationOperationContext context) {
List<Object> list = new ArrayList<Object>();
list.add(context.getReference(field).toString());
list.add(resolve(value, context));
return new BasicDBObject("$ifNull", list);
return new Document("$ifNull", list);
}
private Object resolve(Object value, AggregationOperationContext context) {
@@ -75,7 +76,7 @@ public class IfNullOperator implements AggregationExpression {
return value;
}
return context.getMappedObject(new BasicDBObject("$set", value)).get("$set");
return context.getMappedObject(new Document("$set", value)).get("$set");
}
/**

View File

@@ -15,11 +15,9 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Encapsulates the {@code $limit}-operation.
* <p>
@@ -46,10 +44,10 @@ public class LimitOperation implements AggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject("$limit", maxElements);
public Document toDocument(AggregationOperationContext context) {
return new Document("$limit", Long.valueOf(maxElements));
}
}

View File

@@ -15,13 +15,11 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
import org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Encapsulates the aggregation framework {@code $lookup}-operation. We recommend to use the static factory method
* {@link Aggregation#lookup(String, String, String, String)} instead of creating instances of this class directly.
@@ -75,19 +73,19 @@ public class LookupOperation implements FieldsExposingAggregationOperation, Inhe
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
public Document toDocument(AggregationOperationContext context) {
BasicDBObject lookupObject = new BasicDBObject();
Document lookupObject = new Document();
lookupObject.append("from", from.getTarget());
lookupObject.append("localField", localField.getTarget());
lookupObject.append("foreignField", foreignField.getTarget());
lookupObject.append("as", as.getTarget());
return new BasicDBObject("$lookup", lookupObject);
return new Document("$lookup", lookupObject);
}
/**

View File

@@ -15,12 +15,10 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Encapsulates the {@code $match}-operation.
* <p>
@@ -51,10 +49,10 @@ public class MatchOperation implements AggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject("$match", context.getMappedObject(criteriaDefinition.getCriteriaObject()));
public Document toDocument(AggregationOperationContext context) {
return new Document("$match", context.getMappedObject(criteriaDefinition.getCriteriaObject()));
}
}

View File

@@ -17,6 +17,8 @@ package org.springframework.data.mongodb.core.aggregation;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.bson.Document;
import org.springframework.util.Assert;
/**
@@ -42,10 +44,10 @@ public class OutOperation implements AggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject("$out", collectionName);
public Document toDocument(AggregationOperationContext context) {
return new Document("$out", collectionName);
}
}

View File

@@ -20,14 +20,12 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
import org.springframework.data.mongodb.core.aggregation.Fields.AggregationField;
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder.FieldProjection;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Encapsulates the aggregation framework {@code $project}-operation.
* <p>
@@ -186,18 +184,18 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
public Document toDocument(AggregationOperationContext context) {
BasicDBObject fieldObject = new BasicDBObject();
Document fieldObject = new Document();
for (Projection projection : projections) {
fieldObject.putAll(projection.toDBObject(context));
fieldObject.putAll(projection.toDocument(context));
}
return new BasicDBObject("$project", fieldObject);
return new Document("$project", fieldObject);
}
/**
@@ -227,11 +225,11 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return this.operation.toDBObject(context);
public Document toDocument(AggregationOperationContext context) {
return this.operation.toDocument(context);
}
/**
@@ -353,11 +351,11 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject(getExposedField().getName(), toMongoExpression(context, expression, params));
public Document toDocument(AggregationOperationContext context) {
return new Document(getExposedField().getName(), toMongoExpression(context, expression, params));
}
protected static Object toMongoExpression(AggregationOperationContext context, String expression,
@@ -643,11 +641,11 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return this.operation.toDBObject(context);
public Document toDocument(AggregationOperationContext context) {
return this.operation.toDocument(context);
}
/**
@@ -684,11 +682,11 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject(name, Fields.UNDERSCORE_ID_REF);
public Document toDocument(AggregationOperationContext context) {
return new Document(name, Fields.UNDERSCORE_ID_REF);
}
}
@@ -753,11 +751,11 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject(field.getName(), renderFieldValue(context));
public Document toDocument(AggregationOperationContext context) {
return new Document(field.getName(), renderFieldValue(context));
}
private Object renderFieldValue(AggregationOperationContext context) {
@@ -809,14 +807,14 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
public Document toDocument(AggregationOperationContext context) {
DBObject inner = new BasicDBObject("$" + operation, getOperationArguments(context));
Document inner = new Document("$" + operation, getOperationArguments(context));
return new BasicDBObject(getField().getName(), inner);
return new Document(getField().getName(), inner);
}
protected List<Object> getOperationArguments(AggregationOperationContext context) {
@@ -899,18 +897,18 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.ProjectionOperation.Projection#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
public Document toDocument(AggregationOperationContext context) {
DBObject nestedObject = new BasicDBObject();
Document nestedObject = new Document();
for (Field field : fields) {
nestedObject.put(field.getName(), context.getReference(field.getTarget()).toString());
}
return new BasicDBObject(name, nestedObject);
return new Document(name, nestedObject);
}
}
@@ -1035,13 +1033,13 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
}
/**
* Renders the current {@link Projection} into a {@link DBObject} based on the given
* Renders the current {@link Projection} into a {@link Document} based on the given
* {@link AggregationOperationContext}.
*
* @param context will never be {@literal null}.
* @return
*/
public abstract DBObject toDBObject(AggregationOperationContext context);
public abstract Document toDocument(AggregationOperationContext context);
}
/**
@@ -1066,8 +1064,8 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject(field.getName(), expression.toDbObject(context));
public Document toDocument(AggregationOperationContext context) {
return new Document(field.getName(), expression.toDbObject(context));
}
}
}

View File

@@ -15,11 +15,9 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Encapsulates the aggregation framework {@code $skip}-operation.
* <p>
@@ -48,10 +46,10 @@ public class SkipOperation implements AggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject("$skip", skipCount);
public Document toDocument(AggregationOperationContext context) {
return new Document("$skip", skipCount);
}
}

View File

@@ -15,15 +15,13 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Encapsulates the aggregation framework {@code $sort}-operation.
* <p>
@@ -60,12 +58,12 @@ public class SortOperation implements AggregationOperation {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
public Document toDocument(AggregationOperationContext context) {
BasicDBObject object = new BasicDBObject();
Document object = new Document();
for (Order order : sort) {
@@ -74,6 +72,6 @@ public class SortOperation implements AggregationOperation {
object.put(reference.getRaw(), order.isAscending() ? 1 : -1);
}
return new BasicDBObject("$sort", object);
return new Document("$sort", object);
}
}

View File

@@ -15,12 +15,12 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import static org.springframework.data.mongodb.util.DBObjectUtils.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.bson.Document;
import org.springframework.core.GenericTypeResolver;
import org.springframework.data.mongodb.core.spel.ExpressionNode;
import org.springframework.data.mongodb.core.spel.ExpressionTransformationContextSupport;
@@ -40,10 +40,6 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Renders the AST of a SpEL expression as a MongoDB Aggregation Framework projection expression.
*
@@ -131,8 +127,8 @@ class SpelExpressionTransformer implements AggregationExpressionTransformer {
* @author Thomas Darimont
* @author Oliver Gierke
*/
private static abstract class ExpressionNodeConversion<T extends ExpressionNode> implements
AggregationExpressionTransformer {
private static abstract class ExpressionNodeConversion<T extends ExpressionNode>
implements AggregationExpressionTransformer {
private final AggregationExpressionTransformer transformer;
private final Class<? extends ExpressionNode> nodeType;
@@ -188,7 +184,7 @@ class SpelExpressionTransformer implements AggregationExpressionTransformer {
* @param context must not be {@literal null}.
* @return
*/
protected Object transform(ExpressionNode node, ExpressionNode parent, DBObject operation,
protected Object transform(ExpressionNode node, ExpressionNode parent, Document operation,
AggregationExpressionTransformationContext<?> context) {
Assert.notNull(node, "ExpressionNode must not be null!");
@@ -236,7 +232,7 @@ class SpelExpressionTransformer implements AggregationExpressionTransformer {
OperatorNode currentNode = context.getCurrentNode();
DBObject operationObject = createOperationObjectAndAddToPreviousArgumentsIfNecessary(context, currentNode);
Document operationObject = createOperationObjectAndAddToPreviousArgumentsIfNecessary(context, currentNode);
Object leftResult = transform(currentNode.getLeft(), currentNode, operationObject, context);
if (currentNode.isUnaryMinus()) {
@@ -249,10 +245,10 @@ class SpelExpressionTransformer implements AggregationExpressionTransformer {
return operationObject;
}
private DBObject createOperationObjectAndAddToPreviousArgumentsIfNecessary(
private Document createOperationObjectAndAddToPreviousArgumentsIfNecessary(
AggregationExpressionTransformationContext<OperatorNode> context, OperatorNode currentNode) {
DBObject nextDbObject = new BasicDBObject(currentNode.getMongoOperator(), new BasicDBList());
Document nextDbObject = new Document(currentNode.getMongoOperator(), new ArrayList<Object>());
if (!context.hasPreviousOperation()) {
return nextDbObject;
@@ -271,10 +267,11 @@ class SpelExpressionTransformer implements AggregationExpressionTransformer {
return nextDbObject;
}
private Object convertUnaryMinusOp(ExpressionTransformationContextSupport<OperatorNode> context, Object leftResult) {
private Object convertUnaryMinusOp(ExpressionTransformationContextSupport<OperatorNode> context,
Object leftResult) {
Object result = leftResult instanceof Number ? leftResult
: new BasicDBObject("$multiply", dbList(-1, leftResult));
: new Document("$multiply", Arrays.<Object> asList(Integer.valueOf(-1), leftResult));
if (leftResult != null && context.hasPreviousOperation()) {
context.addToPreviousOperation(result);
@@ -468,7 +465,7 @@ class SpelExpressionTransformer implements AggregationExpressionTransformer {
args.add(transform(childNode, context));
}
return context.addToPreviousOrReturn(new BasicDBObject(node.getMethodName(), dbList(args.toArray())));
return context.addToPreviousOrReturn(new Document(node.getMethodName(), args));
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.aggregation;
import static org.springframework.data.mongodb.core.aggregation.Fields.*;
import org.bson.Document;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.context.PersistentPropertyPath;
@@ -27,8 +28,6 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.util.Assert;
import com.mongodb.DBObject;
/**
* {@link AggregationOperationContext} aware of a particular type and a {@link MappingContext} to potentially translate
* property references into document field names.
@@ -64,10 +63,10 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperationContext#getMappedObject(com.mongodb.DBObject)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperationContext#getMappedObject(com.mongodb.Document)
*/
@Override
public DBObject getMappedObject(DBObject dbObject) {
public Document getMappedObject(Document dbObject) {
return mapper.getMappedObject(dbObject, mappingContext.getPersistentEntity(type));
}
@@ -93,8 +92,8 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
private FieldReference getReferenceFor(Field field) {
PersistentPropertyPath<MongoPersistentProperty> propertyPath = mappingContext.getPersistentPropertyPath(
field.getTarget(), type);
PersistentPropertyPath<MongoPersistentProperty> propertyPath = mappingContext
.getPersistentPropertyPath(field.getTarget(), type);
Field mappedField = field(propertyPath.getLeafProperty().getName(),
propertyPath.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE));

View File

@@ -15,12 +15,10 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Encapsulates the aggregation framework {@code $unwind}-operation.
* <p>
@@ -87,25 +85,25 @@ public class UnwindOperation
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
public Document toDocument(AggregationOperationContext context) {
String path = context.getReference(field).toString();
if (!preserveNullAndEmptyArrays && arrayIndex == null) {
return new BasicDBObject("$unwind", path);
return new Document("$unwind", path);
}
DBObject unwindArgs = new BasicDBObject();
Document unwindArgs = new Document();
unwindArgs.put("path", path);
if (arrayIndex != null) {
unwindArgs.put("includeArrayIndex", arrayIndex.getName());
}
unwindArgs.put("preserveNullAndEmptyArrays", preserveNullAndEmptyArrays);
return new BasicDBObject("$unwind", unwindArgs);
return new Document("$unwind", unwindArgs);
}
/*

View File

@@ -19,40 +19,46 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.util.BsonUtils;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Wrapper value object for a {@link BasicDBObject} to be able to access raw values by {@link MongoPersistentProperty}
* Wrapper value object for a {@link BasicDocument} to be able to access raw values by {@link MongoPersistentProperty}
* references. The accessors will transparently resolve nested document values that a {@link MongoPersistentProperty}
* might refer to through a path expression in field names.
*
* @author Oliver Gierke
*/
class DBObjectAccessor {
class DocumentAccessor {
private final BasicDBObject dbObject;
private final Bson dbObject;
/**
* Creates a new {@link DBObjectAccessor} for the given {@link DBObject}.
* Creates a new {@link DocumentAccessor} for the given {@link Document}.
*
* @param dbObject must be a {@link BasicDBObject} effectively, must not be {@literal null}.
* @param dbObject must be a {@link BasicDocument} effectively, must not be {@literal null}.
*/
public DBObjectAccessor(DBObject dbObject) {
public DocumentAccessor(Bson dbObject) {
Assert.notNull(dbObject, "DBObject must not be null!");
Assert.isInstanceOf(BasicDBObject.class, dbObject, "Given DBObject must be a BasicDBObject!");
Assert.notNull(dbObject, "Document must not be null!");
this.dbObject = (BasicDBObject) dbObject;
if (!(dbObject instanceof Document) && !(dbObject instanceof DBObject)) {
Assert.isInstanceOf(Document.class, dbObject, "Given Document must be a Document or BasicDBObject!");
}
this.dbObject = dbObject;
}
/**
* Puts the given value into the backing {@link DBObject} based on the coordinates defined through the given
* Puts the given value into the backing {@link Document} based on the coordinates defined through the given
* {@link MongoPersistentProperty}. By default this will be the plain field name. But field names might also consist
* of path traversals so we might need to create intermediate {@link BasicDBObject}s.
* of path traversals so we might need to create intermediate {@link BasicDocument}s.
*
* @param prop must not be {@literal null}.
* @param value
@@ -63,12 +69,12 @@ class DBObjectAccessor {
String fieldName = prop.getFieldName();
if (!fieldName.contains(".")) {
dbObject.put(fieldName, value);
BsonUtils.addToMap(dbObject, fieldName, value);
return;
}
Iterator<String> parts = Arrays.asList(fieldName.split("\\.")).iterator();
DBObject dbObject = this.dbObject;
Bson dbObject = this.dbObject;
while (parts.hasNext()) {
@@ -77,7 +83,7 @@ class DBObjectAccessor {
if (parts.hasNext()) {
dbObject = getOrCreateNestedDbObject(part, dbObject);
} else {
dbObject.put(part, value);
BsonUtils.addToMap(dbObject, part, value);
}
}
}
@@ -95,11 +101,11 @@ class DBObjectAccessor {
String fieldName = property.getFieldName();
if (!fieldName.contains(".")) {
return this.dbObject.get(fieldName);
return BsonUtils.asMap(this.dbObject).get(fieldName);
}
Iterator<String> parts = Arrays.asList(fieldName.split("\\.")).iterator();
Map<String, Object> source = this.dbObject;
Map<String, Object> source = BsonUtils.asMap(this.dbObject);
Object result = null;
while (source != null && parts.hasNext()) {
@@ -128,11 +134,25 @@ class DBObjectAccessor {
String fieldName = property.getFieldName();
if (!fieldName.contains(".")) {
return this.dbObject.containsField(fieldName);
if (this.dbObject instanceof Document) {
return ((Document) this.dbObject).containsKey(fieldName);
}
if (this.dbObject instanceof DBObject) {
return ((DBObject) this.dbObject).containsField(fieldName);
}
}
String[] parts = fieldName.split("\\.");
Map<String, Object> source = this.dbObject;
Map<String, Object> source;
if (this.dbObject instanceof Document) {
source = ((Document) this.dbObject);
}else {
source = ((DBObject) this.dbObject).toMap();
}
Object result = null;
for (int i = 1; i < parts.length; i++) {
@@ -149,7 +169,7 @@ class DBObjectAccessor {
}
/**
* Returns the given source object as map, i.e. {@link BasicDBObject}s and maps as is or {@literal null} otherwise.
* Returns the given source object as map, i.e. {@link BasicDocument}s and maps as is or {@literal null} otherwise.
*
* @param source can be {@literal null}.
* @return
@@ -157,6 +177,10 @@ class DBObjectAccessor {
@SuppressWarnings("unchecked")
private static Map<String, Object> getAsMap(Object source) {
if (source instanceof Document) {
return (Document) source;
}
if (source instanceof BasicDBObject) {
return (BasicDBObject) source;
}
@@ -169,23 +193,23 @@ class DBObjectAccessor {
}
/**
* Returns the {@link DBObject} which either already exists in the given source under the given key, or creates a new
* Returns the {@link Document} which either already exists in the given source under the given key, or creates a new
* nested one, registers it with the source and returns it.
*
* @param key must not be {@literal null} or empty.
* @param source must not be {@literal null}.
* @return
*/
private static DBObject getOrCreateNestedDbObject(String key, DBObject source) {
private static Document getOrCreateNestedDbObject(String key, Bson source) {
Object existing = source.get(key);
Object existing = BsonUtils.asMap(source).get(key);
if (existing instanceof BasicDBObject) {
return (BasicDBObject) existing;
if (existing instanceof Document) {
return (Document) existing;
}
DBObject nested = new BasicDBObject();
source.put(key, nested);
Document nested = new Document();
BsonUtils.addToMap(source, key, nested);
return nested;
}

View File

@@ -17,21 +17,20 @@ package org.springframework.data.mongodb.core.convert;
import java.util.Map;
import org.bson.Document;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import com.mongodb.DBObject;
/**
* {@link PropertyAccessor} to allow entity based field access to {@link DBObject}s.
* {@link PropertyAccessor} to allow entity based field access to {@link Document}s.
*
* @author Oliver Gierke
*/
class DBObjectPropertyAccessor extends MapAccessor {
class DocumentPropertyAccessor extends MapAccessor {
static final MapAccessor INSTANCE = new DBObjectPropertyAccessor();
static final MapAccessor INSTANCE = new DocumentPropertyAccessor();
/*
* (non-Javadoc)
@@ -39,7 +38,7 @@ class DBObjectPropertyAccessor extends MapAccessor {
*/
@Override
public Class<?>[] getSpecificTargetClasses() {
return new Class[] { DBObject.class };
return new Class[] { Document.class };
}
/*

View File

@@ -15,13 +15,13 @@
*/
package org.springframework.data.mongodb.core.convert;
import org.bson.Document;
import java.util.List;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
/**
@@ -66,7 +66,7 @@ public interface DbRefResolver {
* @return
* @since 1.7
*/
DBObject fetch(DBRef dbRef);
Document fetch(DBRef dbRef);
/**
* Loads a given {@link List} of {@link DBRef}s from the datasource in one batch. The resulting {@link List} of
@@ -78,5 +78,5 @@ public interface DbRefResolver {
* @throws InvalidDataAccessApiUsageException in case not all {@link DBRef} target the same collection.
* @since 1.10
*/
List<DBObject> bulkFetch(List<DBRef> dbRefs);
List<Document> bulkFetch(List<DBRef> dbRefs);
}

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.mongodb.core.convert;
import org.bson.Document;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator;
@@ -23,8 +24,6 @@ import org.springframework.data.mapping.model.SpELExpressionEvaluator;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
/**
@@ -42,7 +41,8 @@ class DefaultDbRefProxyHandler implements DbRefProxyHandler {
* @param mappingContext must not be {@literal null}.
*/
public DefaultDbRefProxyHandler(SpELContext spELContext,
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext, ValueResolver resolver) {
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext,
ValueResolver resolver) {
this.spELContext = spELContext;
this.mappingContext = mappingContext;
@@ -70,7 +70,7 @@ class DefaultDbRefProxyHandler implements DbRefProxyHandler {
SpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(proxy, spELContext);
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(proxy);
DBObject object = new BasicDBObject(idProperty.getFieldName(), source.getId());
Document object = new Document(idProperty.getFieldName(), source.getId());
ObjectPath objectPath = ObjectPath.ROOT.push(proxy, entity, null);
accessor.setProperty(idProperty, resolver.getValueInternal(idProperty, object, evaluator, objectPath));

View File

@@ -27,8 +27,14 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.client.MongoDatabase;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.bson.Document;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
@@ -45,10 +51,6 @@ import org.springframework.objenesis.ObjenesisStd;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
/**
@@ -113,7 +115,7 @@ public class DefaultDbRefResolver implements DbRefResolver {
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#fetch(com.mongodb.DBRef)
*/
@Override
public DBObject fetch(DBRef dbRef) {
public Document fetch(DBRef dbRef) {
return ReflectiveDBRefResolver.fetch(mongoDbFactory, dbRef);
}
@@ -122,7 +124,7 @@ public class DefaultDbRefResolver implements DbRefResolver {
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#bulkFetch(java.util.List)
*/
@Override
public List<DBObject> bulkFetch(List<DBRef> refs) {
public List<Document> bulkFetch(List<DBRef> refs) {
Assert.notNull(mongoDbFactory, "Factory must not be null!");
Assert.notNull(refs, "DBRef to fetch must not be null!");
@@ -144,9 +146,10 @@ public class DefaultDbRefResolver implements DbRefResolver {
ids.add(ref.getId());
}
DB db = mongoDbFactory.getDb();
List<DBObject> result = db.getCollection(collection)
.find(new BasicDBObjectBuilder().add("_id", new BasicDBObject("$in", ids)).get()).toArray();
MongoDatabase db = mongoDbFactory.getDb();
List<Document> result = new ArrayList<>();
db.getCollection(collection)
.find(new Document("_id", new Document("$in", ids))).into(result);
Collections.sort(result, new DbRefByReferencePositionComparator(ids));
return result;
}
@@ -446,7 +449,7 @@ public class DefaultDbRefResolver implements DbRefResolver {
* @author Oliver Gierke
* @since 1.10
*/
private static class DbRefByReferencePositionComparator implements Comparator<DBObject> {
private static class DbRefByReferencePositionComparator implements Comparator<Document> {
private final List<Object> reference;
@@ -466,7 +469,7 @@ public class DefaultDbRefResolver implements DbRefResolver {
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare(DBObject o1, DBObject o2) {
public int compare(Document o1, Document o2) {
return Integer.compare(reference.indexOf(o1.get("_id")), reference.indexOf(o2.get("_id")));
}
}

View File

@@ -15,11 +15,11 @@
*/
package org.springframework.data.mongodb.core.convert;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import com.mongodb.DBObject;
/**
* Default implementation of {@link DbRefResolverCallback}.
*
@@ -27,13 +27,13 @@ import com.mongodb.DBObject;
*/
class DefaultDbRefResolverCallback implements DbRefResolverCallback {
private final DBObject surroundingObject;
private final Bson surroundingObject;
private final ObjectPath path;
private final ValueResolver resolver;
private final SpELExpressionEvaluator evaluator;
/**
* Creates a new {@link DefaultDbRefResolverCallback} using the given {@link DBObject}, {@link ObjectPath},
* Creates a new {@link DefaultDbRefResolverCallback} using the given {@link Document}, {@link ObjectPath},
* {@link ValueResolver} and {@link SpELExpressionEvaluator}.
*
* @param surroundingObject must not be {@literal null}.
@@ -41,7 +41,7 @@ class DefaultDbRefResolverCallback implements DbRefResolverCallback {
* @param evaluator must not be {@literal null}.
* @param resolver must not be {@literal null}.
*/
public DefaultDbRefResolverCallback(DBObject surroundingObject, ObjectPath path, SpELExpressionEvaluator evaluator,
public DefaultDbRefResolverCallback(Bson surroundingObject, ObjectPath path, SpELExpressionEvaluator evaluator,
ValueResolver resolver) {
this.surroundingObject = surroundingObject;

View File

@@ -20,6 +20,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.data.convert.DefaultTypeMapper;
import org.springframework.data.convert.SimpleTypeInformationMapper;
import org.springframework.data.convert.TypeAliasAccessor;
@@ -30,19 +32,18 @@ import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
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}
* information in {@link Document}. 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
* @author Thomas Darimont
*/
public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implements MongoTypeMapper {
public class DefaultMongoTypeMapper extends DefaultTypeMapper<Bson> implements MongoTypeMapper {
public static final String DEFAULT_TYPE_KEY = "_class";
@SuppressWarnings("rawtypes") //
@@ -50,7 +51,7 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implemen
@SuppressWarnings("rawtypes") //
private static final TypeInformation<Map> MAP_TYPE_INFO = ClassTypeInformation.from(Map.class);
private final TypeAliasAccessor<DBObject> accessor;
private final TypeAliasAccessor<Bson> accessor;
private final String typeKey;
public DefaultMongoTypeMapper() {
@@ -62,15 +63,15 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implemen
}
public DefaultMongoTypeMapper(String typeKey, MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext) {
this(typeKey, new DBObjectTypeAliasAccessor(typeKey), mappingContext,
this(typeKey, new DocumentTypeAliasAccessor(typeKey), mappingContext,
Arrays.asList(new SimpleTypeInformationMapper()));
}
public DefaultMongoTypeMapper(String typeKey, List<? extends TypeInformationMapper> mappers) {
this(typeKey, new DBObjectTypeAliasAccessor(typeKey), null, mappers);
this(typeKey, new DocumentTypeAliasAccessor(typeKey), null, mappers);
}
private DefaultMongoTypeMapper(String typeKey, TypeAliasAccessor<DBObject> accessor,
private DefaultMongoTypeMapper(String typeKey, TypeAliasAccessor<Bson> accessor,
MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext,
List<? extends TypeInformationMapper> mappers) {
@@ -93,7 +94,7 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implemen
* @see org.springframework.data.mongodb.core.convert.MongoTypeMapper#writeTypeRestrictions(java.util.Set)
*/
@Override
public void writeTypeRestrictions(DBObject result, Set<Class<?>> restrictedTypes) {
public void writeTypeRestrictions(Document result, Set<Class<?>> restrictedTypes) {
if (restrictedTypes == null || restrictedTypes.isEmpty()) {
return;
@@ -110,27 +111,28 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implemen
}
}
accessor.writeTypeTo(result, new BasicDBObject("$in", restrictedMappedTypes));
accessor.writeTypeTo(result, new Document("$in", restrictedMappedTypes));
}
/* (non-Javadoc)
* @see org.springframework.data.convert.DefaultTypeMapper#getFallbackTypeFor(java.lang.Object)
*/
@Override
protected TypeInformation<?> getFallbackTypeFor(DBObject source) {
protected TypeInformation<?> getFallbackTypeFor(Bson source) {
return source instanceof BasicDBList ? LIST_TYPE_INFO : MAP_TYPE_INFO;
}
/**
* {@link TypeAliasAccessor} to store aliases in a {@link DBObject}.
* {@link TypeAliasAccessor} to store aliases in a {@link Document}.
*
* @author Oliver Gierke
*/
public static final class DBObjectTypeAliasAccessor implements TypeAliasAccessor<DBObject> {
public static final class DocumentTypeAliasAccessor implements TypeAliasAccessor<Bson> {
private final String typeKey;
public DBObjectTypeAliasAccessor(String typeKey) {
public DocumentTypeAliasAccessor(String typeKey) {
this.typeKey = typeKey;
}
@@ -138,22 +140,35 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implemen
* (non-Javadoc)
* @see org.springframework.data.convert.TypeAliasAccessor#readAliasFrom(java.lang.Object)
*/
public Object readAliasFrom(DBObject source) {
public Object readAliasFrom(Bson source) {
if (source instanceof BasicDBList) {
if (source instanceof List) {
return null;
}
return source.get(typeKey);
if (source instanceof Document) {
return ((Document) source).get(typeKey);
} else if (source instanceof DBObject) {
return ((DBObject) source).get(typeKey);
}
throw new IllegalArgumentException("Cannot read alias from " + source.getClass());
}
/*
* (non-Javadoc)
* @see org.springframework.data.convert.TypeAliasAccessor#writeTypeTo(java.lang.Object, java.lang.Object)
*/
public void writeTypeTo(DBObject sink, Object alias) {
public void writeTypeTo(Bson sink, Object alias) {
if (typeKey != null) {
sink.put(typeKey, alias);
if (sink instanceof Document) {
((Document) sink).put(typeKey, alias);
} else if (sink instanceof DBObject) {
((DBObject) sink).put(typeKey, alias);
}
}
}
}

View File

@@ -20,6 +20,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.bson.Document;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
@@ -44,8 +45,6 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Wrapper class to contain useful geo structure converters for the usage with Mongo.
@@ -100,7 +99,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToPointConverter implements Converter<DBObject, Point> {
static enum DbObjectToPointConverter implements Converter<Document, Point> {
INSTANCE;
@@ -109,7 +108,7 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public Point convert(DBObject source) {
public Point convert(Document source) {
if (source == null) {
return null;
@@ -117,7 +116,7 @@ abstract class GeoConverters {
Assert.isTrue(source.keySet().size() == 2, "Source must contain 2 elements");
if (source.containsField("type")) {
if (source.containsKey("type")) {
return DbObjectToGeoJsonPointConverter.INSTANCE.convert(source);
}
@@ -131,7 +130,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum PointToDbObjectConverter implements Converter<Point, DBObject> {
static enum PointToDbObjectConverter implements Converter<Point, Document> {
INSTANCE;
@@ -140,8 +139,8 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(Point source) {
return source == null ? null : new BasicDBObject("x", source.getX()).append("y", source.getY());
public Document convert(Point source) {
return source == null ? null : new Document("x", source.getX()).append("y", source.getY());
}
}
@@ -152,7 +151,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@WritingConverter
static enum BoxToDbObjectConverter implements Converter<Box, DBObject> {
static enum BoxToDbObjectConverter implements Converter<Box, Document> {
INSTANCE;
@@ -161,13 +160,13 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(Box source) {
public Document convert(Box source) {
if (source == null) {
return null;
}
BasicDBObject result = new BasicDBObject();
Document result = new Document();
result.put("first", PointToDbObjectConverter.INSTANCE.convert(source.getFirst()));
result.put("second", PointToDbObjectConverter.INSTANCE.convert(source.getSecond()));
return result;
@@ -181,7 +180,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToBoxConverter implements Converter<DBObject, Box> {
static enum DbObjectToBoxConverter implements Converter<Document, Box> {
INSTANCE;
@@ -190,14 +189,14 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public Box convert(DBObject source) {
public Box convert(Document source) {
if (source == null) {
return null;
}
Point first = DbObjectToPointConverter.INSTANCE.convert((DBObject) source.get("first"));
Point second = DbObjectToPointConverter.INSTANCE.convert((DBObject) source.get("second"));
Point first = DbObjectToPointConverter.INSTANCE.convert((Document) source.get("first"));
Point second = DbObjectToPointConverter.INSTANCE.convert((Document) source.get("second"));
return new Box(first, second);
}
@@ -209,7 +208,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum CircleToDbObjectConverter implements Converter<Circle, DBObject> {
static enum CircleToDbObjectConverter implements Converter<Circle, Document> {
INSTANCE;
@@ -218,13 +217,13 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(Circle source) {
public Document convert(Circle source) {
if (source == null) {
return null;
}
DBObject result = new BasicDBObject();
Document result = new Document();
result.put("center", PointToDbObjectConverter.INSTANCE.convert(source.getCenter()));
result.put("radius", source.getRadius().getNormalizedValue());
result.put("metric", source.getRadius().getMetric().toString());
@@ -233,13 +232,13 @@ abstract class GeoConverters {
}
/**
* Converts a {@link DBObject} into a {@link Circle}.
* Converts a {@link Document} into a {@link Circle}.
*
* @author Thomas Darimont
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToCircleConverter implements Converter<DBObject, Circle> {
static enum DbObjectToCircleConverter implements Converter<Document, Circle> {
INSTANCE;
@@ -248,18 +247,18 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public Circle convert(DBObject source) {
public Circle convert(Document source) {
if (source == null) {
return null;
}
DBObject center = (DBObject) source.get("center");
Document center = (Document) source.get("center");
Double radius = (Double) source.get("radius");
Distance distance = new Distance(radius);
if (source.containsField("metric")) {
if (source.containsKey("metric")) {
String metricString = (String) source.get("metric");
Assert.notNull(metricString, "Metric must not be null!");
@@ -280,7 +279,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum SphereToDbObjectConverter implements Converter<Sphere, DBObject> {
static enum SphereToDbObjectConverter implements Converter<Sphere, Document> {
INSTANCE;
@@ -289,13 +288,13 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(Sphere source) {
public Document convert(Sphere source) {
if (source == null) {
return null;
}
DBObject result = new BasicDBObject();
Document result = new Document();
result.put("center", PointToDbObjectConverter.INSTANCE.convert(source.getCenter()));
result.put("radius", source.getRadius().getNormalizedValue());
result.put("metric", source.getRadius().getMetric().toString());
@@ -310,7 +309,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToSphereConverter implements Converter<DBObject, Sphere> {
static enum DbObjectToSphereConverter implements Converter<Document, Sphere> {
INSTANCE;
@@ -319,18 +318,18 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public Sphere convert(DBObject source) {
public Sphere convert(Document source) {
if (source == null) {
return null;
}
DBObject center = (DBObject) source.get("center");
Document center = (Document) source.get("center");
Double radius = (Double) source.get("radius");
Distance distance = new Distance(radius);
if (source.containsField("metric")) {
if (source.containsKey("metric")) {
String metricString = (String) source.get("metric");
Assert.notNull(metricString, "Metric must not be null!");
@@ -351,7 +350,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum PolygonToDbObjectConverter implements Converter<Polygon, DBObject> {
static enum PolygonToDbObjectConverter implements Converter<Polygon, Document> {
INSTANCE;
@@ -360,20 +359,20 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(Polygon source) {
public Document convert(Polygon source) {
if (source == null) {
return null;
}
List<Point> points = source.getPoints();
List<DBObject> pointTuples = new ArrayList<DBObject>(points.size());
List<Document> pointTuples = new ArrayList<Document>(points.size());
for (Point point : points) {
pointTuples.add(PointToDbObjectConverter.INSTANCE.convert(point));
}
DBObject result = new BasicDBObject();
Document result = new Document();
result.put("points", pointTuples);
return result;
}
@@ -386,7 +385,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToPolygonConverter implements Converter<DBObject, Polygon> {
static enum DbObjectToPolygonConverter implements Converter<Document, Polygon> {
INSTANCE;
@@ -396,16 +395,16 @@ abstract class GeoConverters {
*/
@Override
@SuppressWarnings({ "unchecked" })
public Polygon convert(DBObject source) {
public Polygon convert(Document source) {
if (source == null) {
return null;
}
List<DBObject> points = (List<DBObject>) source.get("points");
List<Document> points = (List<Document>) source.get("points");
List<Point> newPoints = new ArrayList<Point>(points.size());
for (DBObject element : points) {
for (Document element : points) {
Assert.notNull(element, "Point elements of polygon must not be null!");
newPoints.add(DbObjectToPointConverter.INSTANCE.convert(element));
@@ -421,7 +420,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum GeoCommandToDbObjectConverter implements Converter<GeoCommand, DBObject> {
static enum GeoCommandToDbObjectConverter implements Converter<GeoCommand, Document> {
INSTANCE;
@@ -431,13 +430,13 @@ abstract class GeoConverters {
*/
@Override
@SuppressWarnings("rawtypes")
public DBObject convert(GeoCommand source) {
public Document convert(GeoCommand source) {
if (source == null) {
return null;
}
BasicDBList argument = new BasicDBList();
List argument = new ArrayList();
Shape shape = source.getShape();
@@ -472,7 +471,7 @@ abstract class GeoConverters {
argument.add(((Sphere) shape).getRadius().getNormalizedValue());
}
return new BasicDBObject(source.getCommand(), argument);
return new Document(source.getCommand(), argument);
}
}
@@ -481,7 +480,7 @@ abstract class GeoConverters {
* @since 1.7
*/
@SuppressWarnings("rawtypes")
static enum GeoJsonToDbObjectConverter implements Converter<GeoJson, DBObject> {
static enum GeoJsonToDbObjectConverter implements Converter<GeoJson, Document> {
INSTANCE;
@@ -490,17 +489,17 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(GeoJson source) {
public Document convert(GeoJson source) {
if (source == null) {
return null;
}
DBObject dbo = new BasicDBObject("type", source.getType());
Document dbo = new Document("type", source.getType());
if (source instanceof GeoJsonGeometryCollection) {
BasicDBList dbl = new BasicDBList();
List dbl = new ArrayList();
for (GeoJson geometry : ((GeoJsonGeometryCollection) source).getCoordinates()) {
dbl.add(convert(geometry));
@@ -523,7 +522,7 @@ abstract class GeoConverters {
if (candidate instanceof Iterable) {
BasicDBList dbl = new BasicDBList();
List dbl = new ArrayList();
for (Object element : (Iterable) candidate) {
dbl.add(convertIfNecessarry(element));
@@ -544,7 +543,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
static enum GeoJsonPointToDbObjectConverter implements Converter<GeoJsonPoint, DBObject> {
static enum GeoJsonPointToDbObjectConverter implements Converter<GeoJsonPoint, Document> {
INSTANCE;
@@ -553,7 +552,7 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(GeoJsonPoint source) {
public Document convert(GeoJsonPoint source) {
return GeoJsonToDbObjectConverter.INSTANCE.convert(source);
}
}
@@ -562,7 +561,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
static enum GeoJsonPolygonToDbObjectConverter implements Converter<GeoJsonPolygon, DBObject> {
static enum GeoJsonPolygonToDbObjectConverter implements Converter<GeoJsonPolygon, Document> {
INSTANCE;
@@ -571,7 +570,7 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(GeoJsonPolygon source) {
public Document convert(GeoJsonPolygon source) {
return GeoJsonToDbObjectConverter.INSTANCE.convert(source);
}
}
@@ -580,7 +579,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonPointConverter implements Converter<DBObject, GeoJsonPoint> {
static enum DbObjectToGeoJsonPointConverter implements Converter<Document, GeoJsonPoint> {
INSTANCE;
@@ -590,7 +589,7 @@ abstract class GeoConverters {
*/
@Override
@SuppressWarnings("unchecked")
public GeoJsonPoint convert(DBObject source) {
public GeoJsonPoint convert(Document source) {
if (source == null) {
return null;
@@ -608,7 +607,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonPolygonConverter implements Converter<DBObject, GeoJsonPolygon> {
static enum DbObjectToGeoJsonPolygonConverter implements Converter<Document, GeoJsonPolygon> {
INSTANCE;
@@ -617,7 +616,7 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonPolygon convert(DBObject source) {
public GeoJsonPolygon convert(Document source) {
if (source == null) {
return null;
@@ -626,7 +625,7 @@ abstract class GeoConverters {
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "Polygon"),
String.format("Cannot convert type '%s' to Polygon.", source.get("type")));
return toGeoJsonPolygon((BasicDBList) source.get("coordinates"));
return toGeoJsonPolygon((List) source.get("coordinates"));
}
}
@@ -634,7 +633,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonMultiPolygonConverter implements Converter<DBObject, GeoJsonMultiPolygon> {
static enum DbObjectToGeoJsonMultiPolygonConverter implements Converter<Document, GeoJsonMultiPolygon> {
INSTANCE;
@@ -643,7 +642,7 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonMultiPolygon convert(DBObject source) {
public GeoJsonMultiPolygon convert(Document source) {
if (source == null) {
return null;
@@ -652,11 +651,11 @@ abstract class GeoConverters {
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "MultiPolygon"),
String.format("Cannot convert type '%s' to MultiPolygon.", source.get("type")));
BasicDBList dbl = (BasicDBList) source.get("coordinates");
List dbl = (List) source.get("coordinates");
List<GeoJsonPolygon> polygones = new ArrayList<GeoJsonPolygon>();
for (Object polygon : dbl) {
polygones.add(toGeoJsonPolygon((BasicDBList) polygon));
polygones.add(toGeoJsonPolygon((List) polygon));
}
return new GeoJsonMultiPolygon(polygones);
@@ -667,7 +666,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonLineStringConverter implements Converter<DBObject, GeoJsonLineString> {
static enum DbObjectToGeoJsonLineStringConverter implements Converter<Document, GeoJsonLineString> {
INSTANCE;
@@ -676,7 +675,7 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonLineString convert(DBObject source) {
public GeoJsonLineString convert(Document source) {
if (source == null) {
return null;
@@ -685,7 +684,7 @@ abstract class GeoConverters {
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "LineString"),
String.format("Cannot convert type '%s' to LineString.", source.get("type")));
BasicDBList cords = (BasicDBList) source.get("coordinates");
List cords = (List) source.get("coordinates");
return new GeoJsonLineString(toListOfPoint(cords));
}
@@ -695,7 +694,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonMultiPointConverter implements Converter<DBObject, GeoJsonMultiPoint> {
static enum DbObjectToGeoJsonMultiPointConverter implements Converter<Document, GeoJsonMultiPoint> {
INSTANCE;
@@ -704,7 +703,7 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonMultiPoint convert(DBObject source) {
public GeoJsonMultiPoint convert(Document source) {
if (source == null) {
return null;
@@ -713,7 +712,7 @@ abstract class GeoConverters {
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "MultiPoint"),
String.format("Cannot convert type '%s' to MultiPoint.", source.get("type")));
BasicDBList cords = (BasicDBList) source.get("coordinates");
List cords = (List) source.get("coordinates");
return new GeoJsonMultiPoint(toListOfPoint(cords));
}
@@ -723,7 +722,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonMultiLineStringConverter implements Converter<DBObject, GeoJsonMultiLineString> {
static enum DbObjectToGeoJsonMultiLineStringConverter implements Converter<Document, GeoJsonMultiLineString> {
INSTANCE;
@@ -732,7 +731,7 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonMultiLineString convert(DBObject source) {
public GeoJsonMultiLineString convert(Document source) {
if (source == null) {
return null;
@@ -742,10 +741,10 @@ abstract class GeoConverters {
String.format("Cannot convert type '%s' to MultiLineString.", source.get("type")));
List<GeoJsonLineString> lines = new ArrayList<GeoJsonLineString>();
BasicDBList cords = (BasicDBList) source.get("coordinates");
List cords = (List) source.get("coordinates");
for (Object line : cords) {
lines.add(new GeoJsonLineString(toListOfPoint((BasicDBList) line)));
lines.add(new GeoJsonLineString(toListOfPoint((List) line)));
}
return new GeoJsonMultiLineString(lines);
}
@@ -755,7 +754,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonGeometryCollectionConverter implements Converter<DBObject, GeoJsonGeometryCollection> {
static enum DbObjectToGeoJsonGeometryCollectionConverter implements Converter<Document, GeoJsonGeometryCollection> {
INSTANCE;
@@ -765,7 +764,7 @@ abstract class GeoConverters {
*/
@SuppressWarnings("rawtypes")
@Override
public GeoJsonGeometryCollection convert(DBObject source) {
public GeoJsonGeometryCollection convert(Document source) {
if (source == null) {
return null;
@@ -776,13 +775,13 @@ abstract class GeoConverters {
List<GeoJson<?>> geometries = new ArrayList<GeoJson<?>>();
for (Object o : (List) source.get("geometries")) {
geometries.add(convertGeometries((DBObject) o));
geometries.add(convertGeometries((Document) o));
}
return new GeoJsonGeometryCollection(geometries);
}
private static GeoJson<?> convertGeometries(DBObject source) {
private static GeoJson<?> convertGeometries(Document source) {
Object type = source.get("type");
if (ObjectUtils.nullSafeEquals(type, "Point")) {
@@ -824,7 +823,7 @@ abstract class GeoConverters {
* @since 1.7
*/
@SuppressWarnings("unchecked")
static List<Point> toListOfPoint(BasicDBList listOfCoordinatePairs) {
static List<Point> toListOfPoint(List listOfCoordinatePairs) {
List<Point> points = new ArrayList<Point>();
@@ -846,7 +845,7 @@ abstract class GeoConverters {
* @return
* @since 1.7
*/
static GeoJsonPolygon toGeoJsonPolygon(BasicDBList dbList) {
return new GeoJsonPolygon(toListOfPoint((BasicDBList) dbList.get(0)));
static GeoJsonPolygon toGeoJsonPolygon(List dbList) {
return new GeoJsonPolygon(toListOfPoint((List) dbList.get(0)));
}
}

View File

@@ -26,6 +26,8 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
@@ -64,6 +66,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
@@ -72,7 +75,7 @@ import com.mongodb.DBRef;
/**
* {@link MongoConverter} that uses a {@link MappingContext} to do sophisticated mapping of domain objects to
* {@link DBObject}.
* {@link Document}.
*
* @author Oliver Gierke
* @author Jon Brisbin
@@ -117,7 +120,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
this.typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, mappingContext);
this.idMapper = new QueryMapper(this);
this.spELContext = new SpELContext(DBObjectPropertyAccessor.INSTANCE);
this.spELContext = new SpELContext(DocumentPropertyAccessor.INSTANCE);
}
/**
@@ -134,8 +137,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
/**
* Configures the {@link MongoTypeMapper} to be used to add type information to {@link DBObject}s created by the
* converter and how to lookup type information from {@link DBObject}s when reading them. Uses a
* Configures the {@link MongoTypeMapper} to be used to add type information to {@link Document}s created by the
* converter and how to lookup type information from {@link Document}s when reading them. Uses a
* {@link DefaultMongoTypeMapper} by default. Setting this to {@literal null} will reset the {@link TypeMapper} to the
* default one.
*
@@ -187,18 +190,18 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.core.MongoReader#read(java.lang.Class, com.mongodb.DBObject)
* @see org.springframework.data.mongodb.core.core.MongoReader#read(java.lang.Class, com.mongodb.Document)
*/
public <S extends Object> S read(Class<S> clazz, final DBObject dbo) {
public <S extends Object> S read(Class<S> clazz, final Bson dbo) {
return read(ClassTypeInformation.from(clazz), dbo);
}
protected <S extends Object> S read(TypeInformation<S> type, DBObject dbo) {
protected <S extends Object> S read(TypeInformation<S> type, Bson dbo) {
return read(type, dbo, ObjectPath.ROOT);
}
@SuppressWarnings("unchecked")
private <S extends Object> S read(TypeInformation<S> type, DBObject dbo, ObjectPath path) {
private <S extends Object> S read(TypeInformation<S> type, Bson dbo, ObjectPath path) {
if (null == dbo) {
return null;
@@ -215,18 +218,25 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return (S) dbo;
}
if (typeToUse.isCollectionLike() && dbo instanceof BasicDBList) {
return (S) readCollectionOrArray(typeToUse, (BasicDBList) dbo, path);
if (Document.class.isAssignableFrom(rawType)) {
return (S) dbo;
}
if (typeToUse.isCollectionLike() && dbo instanceof List) {
return (S) readCollectionOrArray(typeToUse, (List) dbo, path);
}
if (typeToUse.isMap()) {
return (S) readMap(typeToUse, dbo, path);
}
if (dbo instanceof BasicDBList) {
if (dbo instanceof Collection) {
throw new MappingException(String.format(INCOMPATIBLE_TYPES, dbo, BasicDBList.class, typeToUse.getType(), path));
}
if (typeToUse.equals(ClassTypeInformation.OBJECT)) {
return (S) dbo;
}
// Retrieve persistent entity info
MongoPersistentEntity<S> persistentEntity = (MongoPersistentEntity<S>) mappingContext
.getPersistentEntity(typeToUse);
@@ -238,7 +248,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
private ParameterValueProvider<MongoPersistentProperty> getParameterProvider(MongoPersistentEntity<?> entity,
DBObject source, DefaultSpELExpressionEvaluator evaluator, ObjectPath path) {
Bson source, DefaultSpELExpressionEvaluator evaluator, ObjectPath path) {
MongoDbPropertyValueProvider provider = new MongoDbPropertyValueProvider(source, evaluator, path);
PersistentEntityParameterValueProvider<MongoPersistentProperty> parameterProvider = new PersistentEntityParameterValueProvider<MongoPersistentProperty>(
@@ -248,7 +258,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
path);
}
private <S extends Object> S read(final MongoPersistentEntity<S> entity, final DBObject dbo, final ObjectPath path) {
private <S extends Object> S read(final MongoPersistentEntity<S> entity, final Bson dbo, final ObjectPath path) {
final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(dbo, spELContext);
@@ -264,14 +274,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
// make sure id property is set before all other properties
Object idValue = null;
final DBObjectAccessor dbObjectAccessor = new DBObjectAccessor(dbo);
DocumentAccessor documentAccessor = new DocumentAccessor(dbo);
if (idProperty != null && dbObjectAccessor.hasValue(idProperty)) {
if (idProperty != null && documentAccessor.hasValue(idProperty)) {
idValue = getValueInternal(idProperty, dbo, evaluator, path);
accessor.setProperty(idProperty, idValue);
}
final ObjectPath currentPath = path.push(result, entity, idValue != null ? dbObjectAccessor.get(idProperty) : null);
final ObjectPath currentPath = path.push(result, entity, idValue != null ? documentAccessor.get(idProperty) : null);
// Set properties not already set in the constructor
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
@@ -282,7 +292,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return;
}
if (entity.isConstructorArgument(prop) || !dbObjectAccessor.hasValue(prop)) {
if (entity.isConstructorArgument(prop) || !documentAccessor.hasValue(prop)) {
return;
}
@@ -295,7 +305,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
public void doWithAssociation(Association<MongoPersistentProperty> association) {
final MongoPersistentProperty property = association.getInverse();
Object value = dbObjectAccessor.get(property);
Object value = documentAccessor.get(property);
if (value == null || entity.isConstructorArgument(property)) {
return;
@@ -337,28 +347,31 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
/**
* Root entry method into write conversion. Adds a type discriminator to the {@link DBObject}. Shouldn't be called for
* Root entry method into write conversion. Adds a type discriminator to the {@link Document}. Shouldn't be called for
* nested conversions.
*
* @see org.springframework.data.mongodb.core.core.convert.MongoWriter#write(java.lang.Object, com.mongodb.DBObject)
* @see org.springframework.data.mongodb.core.core.convert.MongoWriter#write(java.lang.Object, com.mongodb.Document)
*/
public void write(final Object obj, final DBObject dbo) {
public void write(final Object obj, final Bson dbo) {
if (null == obj) {
return;
}
Class<?> entityType = obj.getClass();
boolean handledByCustomConverter = conversions.getCustomWriteTarget(entityType, DBObject.class) != null;
boolean handledByCustomConverter = conversions.getCustomWriteTarget(entityType, Document.class) != null;
TypeInformation<? extends Object> type = ClassTypeInformation.from(entityType);
if (!handledByCustomConverter && !(dbo instanceof BasicDBList)) {
if (!handledByCustomConverter && !(dbo instanceof Collection)) {
typeMapper.writeType(type, dbo);
}
Object target = obj instanceof LazyLoadingProxy ? ((LazyLoadingProxy) obj).getTarget() : obj;
writeInternal(target, dbo, type);
if (asMap(dbo).containsKey("_is") && asMap(dbo).get("_id") == null) {
removeFromMap(dbo, "_id");
}
}
/**
@@ -368,18 +381,18 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @param dbo
*/
@SuppressWarnings("unchecked")
protected void writeInternal(final Object obj, final DBObject dbo, final TypeInformation<?> typeHint) {
protected void writeInternal(final Object obj, final Bson dbo, final TypeInformation<?> typeHint) {
if (null == obj) {
return;
}
Class<?> entityType = obj.getClass();
Class<?> customTarget = conversions.getCustomWriteTarget(entityType, DBObject.class);
Class<?> customTarget = conversions.getCustomWriteTarget(entityType, Document.class);
if (customTarget != null) {
DBObject result = conversionService.convert(obj, DBObject.class);
dbo.putAll(result);
Document result = conversionService.convert(obj, Document.class);
addAllToMap(dbo, result);
return;
}
@@ -389,7 +402,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
if (Collection.class.isAssignableFrom(entityType)) {
writeCollectionInternal((Collection<?>) obj, ClassTypeInformation.LIST, (BasicDBList) dbo);
writeCollectionInternal((Collection<?>) obj, ClassTypeInformation.LIST, (List) dbo);
return;
}
@@ -398,7 +411,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
addCustomTypeKeyIfNecessary(typeHint, obj, dbo);
}
protected void writeInternal(Object obj, final DBObject dbo, MongoPersistentEntity<?> entity) {
protected void writeInternal(Object obj, final Bson dbo, MongoPersistentEntity<?> entity) {
if (obj == null) {
return;
@@ -411,11 +424,11 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(obj);
final MongoPersistentProperty idProperty = entity.getIdProperty();
if (!dbo.containsField("_id") && null != idProperty) {
if (!asMap(dbo).containsKey("_id") && null != idProperty) {
try {
Object id = accessor.getProperty(idProperty);
dbo.put("_id", idMapper.convertId(id));
addToMap(dbo, "_id", idMapper.convertId(id));
} catch (ConversionException ignored) {}
}
@@ -455,25 +468,25 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
@SuppressWarnings({ "unchecked" })
protected void writePropertyInternal(Object obj, DBObject dbo, MongoPersistentProperty prop) {
protected void writePropertyInternal(Object obj, Bson dbo, MongoPersistentProperty prop) {
if (obj == null) {
return;
}
DBObjectAccessor accessor = new DBObjectAccessor(dbo);
DocumentAccessor accessor = new DocumentAccessor(dbo);
TypeInformation<?> valueType = ClassTypeInformation.from(obj.getClass());
TypeInformation<?> type = prop.getTypeInformation();
if (valueType.isCollectionLike()) {
DBObject collectionInternal = createCollection(asCollection(obj), prop);
List collectionInternal = createCollection(asCollection(obj), prop);
accessor.put(prop, collectionInternal);
return;
}
if (valueType.isMap()) {
DBObject mapDbObj = createMap((Map<Object, Object>) obj, prop);
Bson mapDbObj = createMap((Map<Object, Object>) obj, prop);
accessor.put(prop, mapDbObj);
return;
}
@@ -514,8 +527,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
Object existingValue = accessor.get(prop);
BasicDBObject propDbObj = existingValue instanceof BasicDBObject ? (BasicDBObject) existingValue
: new BasicDBObject();
Document propDbObj = existingValue instanceof Document ? (Document) existingValue : new Document();
addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, propDbObj);
MongoPersistentEntity<?> entity = isSubtype(prop.getType(), obj.getClass())
@@ -553,13 +565,13 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @param property must not be {@literal null}.
* @return
*/
protected DBObject createCollection(Collection<?> collection, MongoPersistentProperty property) {
protected List<Object> createCollection(Collection<?> collection, MongoPersistentProperty property) {
if (!property.isDbReference()) {
return writeCollectionInternal(collection, property.getTypeInformation(), new BasicDBList());
return writeCollectionInternal(collection, property.getTypeInformation(), new ArrayList());
}
BasicDBList dbList = new BasicDBList();
List<Object> dbList = new ArrayList<Object>();
for (Object element : collection) {
@@ -581,16 +593,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @param property must not be {@literal null}.
* @return
*/
protected DBObject createMap(Map<Object, Object> map, MongoPersistentProperty property) {
protected Bson createMap(Map<Object, Object> map, MongoPersistentProperty property) {
Assert.notNull(map, "Given map must not be null!");
Assert.notNull(property, "PersistentProperty must not be null!");
if (!property.isDbReference()) {
return writeMapInternal(map, new BasicDBObject(), property.getTypeInformation());
return writeMapInternal(map, new Document(), property.getTypeInformation());
}
BasicDBObject dbObject = new BasicDBObject();
Document dbObject = new Document();
for (Map.Entry<Object, Object> entry : map.entrySet()) {
@@ -618,7 +630,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @param sink the {@link BasicDBList} to write to.
* @return
*/
private BasicDBList writeCollectionInternal(Collection<?> source, TypeInformation<?> type, BasicDBList sink) {
private List writeCollectionInternal(Collection<?> source, TypeInformation<?> type, List sink) {
TypeInformation<?> componentType = type == null ? null : type.getComponentType();
@@ -631,7 +643,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
} else if (element instanceof Collection || elementType.isArray()) {
sink.add(writeCollectionInternal(asCollection(element), componentType, new BasicDBList()));
} else {
BasicDBObject propDbObj = new BasicDBObject();
Document propDbObj = new Document();
writeInternal(element, propDbObj, componentType);
sink.add(propDbObj);
}
@@ -641,14 +653,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
/**
* Writes the given {@link Map} to the given {@link DBObject} considering the given {@link TypeInformation}.
* Writes the given {@link Map} to the given {@link Document} considering the given {@link TypeInformation}.
*
* @param obj must not be {@literal null}.
* @param dbo must not be {@literal null}.
* @param propertyType must not be {@literal null}.
* @return
*/
protected DBObject writeMapInternal(Map<Object, Object> obj, DBObject dbo, TypeInformation<?> propertyType) {
protected Bson writeMapInternal(Map<Object, Object> obj, Bson dbo, TypeInformation<?> propertyType) {
for (Map.Entry<Object, Object> entry : obj.entrySet()) {
@@ -661,14 +673,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
if (val == null || conversions.isSimpleType(val.getClass())) {
writeSimpleInternal(val, dbo, simpleKey);
} else if (val instanceof Collection || val.getClass().isArray()) {
dbo.put(simpleKey,
addToMap(dbo, simpleKey,
writeCollectionInternal(asCollection(val), propertyType.getMapValueType(), new BasicDBList()));
} else {
DBObject newDbo = new BasicDBObject();
Document newDbo = new Document();
TypeInformation<?> valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType()
: ClassTypeInformation.OBJECT;
writeInternal(val, newDbo, valueTypeInfo);
dbo.put(simpleKey, newDbo);
addToMap(dbo, simpleKey, newDbo);
}
} else {
throw new MappingException("Cannot use a complex object as a key value.");
@@ -745,14 +757,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
/**
* Adds custom type information to the given {@link DBObject} if necessary. That is if the value is not the same as
* Adds custom type information to the given {@link Document} if necessary. That is if the value is not the same as
* the one given. This is usually the case if you store a subtype of the actual declared type of the property.
*
* @param type
* @param value must not be {@literal null}.
* @param dbObject must not be {@literal null}.
*/
protected void addCustomTypeKeyIfNecessary(TypeInformation<?> type, Object value, DBObject dbObject) {
protected void addCustomTypeKeyIfNecessary(TypeInformation<?> type, Object value, Bson dbObject) {
TypeInformation<?> actualType = type != null ? type.getActualType() : null;
Class<?> reference = actualType == null ? Object.class : actualType.getType();
@@ -765,18 +777,18 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
/**
* Writes the given simple value to the given {@link DBObject}. Will store enum names for enum values.
* Writes the given simple value to the given {@link Document}. Will store enum names for enum values.
*
* @param value
* @param dbObject must not be {@literal null}.
* @param key must not be {@literal null}.
*/
private void writeSimpleInternal(Object value, DBObject dbObject, String key) {
dbObject.put(key, getPotentiallyConvertedSimpleWrite(value));
private void writeSimpleInternal(Object value, Bson dbObject, String key) {
addToMap(dbObject, key, getPotentiallyConvertedSimpleWrite(value));
}
private void writeSimpleInternal(Object value, DBObject dbObject, MongoPersistentProperty property) {
DBObjectAccessor accessor = new DBObjectAccessor(dbObject);
private void writeSimpleInternal(Object value, Bson dbObject, MongoPersistentProperty property) {
DocumentAccessor accessor = new DocumentAccessor(dbObject);
accessor.put(property, getPotentiallyConvertedSimpleWrite(value));
}
@@ -797,7 +809,15 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
if (customTarget != null) {
return conversionService.convert(value, customTarget);
} else {
} else if (ObjectUtils.isArray(value)) {
if (value instanceof byte[]) {
return value;
}
return asCollection(value);
}
else {
return Enum.class.isAssignableFrom(value.getClass()) ? ((Enum<?>) value).name() : value;
}
}
@@ -868,10 +888,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.ValueResolver#getValueInternal(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, com.mongodb.DBObject, org.springframework.data.mapping.model.SpELExpressionEvaluator, java.lang.Object)
* @see org.springframework.data.mongodb.core.convert.ValueResolver#getValueInternal(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, com.mongodb.Document, org.springframework.data.mapping.model.SpELExpressionEvaluator, java.lang.Object)
*/
@Override
public Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, SpELExpressionEvaluator evaluator,
public Object getValueInternal(MongoPersistentProperty prop, Bson dbo, SpELExpressionEvaluator evaluator,
ObjectPath path) {
return new MongoDbPropertyValueProvider(dbo, evaluator, path).getPropertyValue(prop);
}
@@ -885,7 +905,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @return the converted {@link Collection} or array, will never be {@literal null}.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private Object readCollectionOrArray(TypeInformation<?> targetType, BasicDBList sourceValue, ObjectPath path) {
private Object readCollectionOrArray(TypeInformation<?> targetType, List sourceValue, ObjectPath path) {
Assert.notNull(targetType, "Target type must not be null!");
Assert.notNull(path, "Object path must not be null!");
@@ -910,31 +930,44 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
for (Object dbObjItem : sourceValue) {
if (dbObjItem instanceof DBRef) {
items.add(DBRef.class.equals(rawComponentType) ? dbObjItem
: readAndConvertDBRef((DBRef) dbObjItem, componentType, path, rawComponentType));
} else if (dbObjItem instanceof DBObject) {
items.add(read(componentType, (DBObject) dbObjItem, path));
} else if (dbObjItem instanceof Document) {
items.add(read(componentType, (Document) dbObjItem, path));
} else if (dbObjItem instanceof BasicDBObject) {
items.add(read(componentType, (BasicDBObject) dbObjItem, path));
} else {
if (dbObjItem instanceof Collection) {
if (!rawComponentType.isArray() && !ClassUtils.isAssignable(Iterable.class, rawComponentType)) {
throw new MappingException(
String.format(INCOMPATIBLE_TYPES, dbObjItem, dbObjItem.getClass(), rawComponentType, path));
}
}
if (dbObjItem instanceof List) {
items.add(readCollectionOrArray(ClassTypeInformation.OBJECT, (List) dbObjItem, path));
} else {
items.add(getPotentiallyConvertedSimpleRead(dbObjItem, rawComponentType));
}
}
}
return getPotentiallyConvertedSimpleRead(items, targetType.getType());
}
/**
* Reads the given {@link DBObject} into a {@link Map}. will recursively resolve nested {@link Map}s as well.
* Reads the given {@link Document} into a {@link Map}. will recursively resolve nested {@link Map}s as well.
*
* @param type the {@link Map} {@link TypeInformation} to be used to unmarshall this {@link DBObject}.
* @param type the {@link Map} {@link TypeInformation} to be used to unmarshall this {@link Document}.
* @param dbObject must not be {@literal null}
* @param path must not be {@literal null}
* @return
*/
@SuppressWarnings("unchecked")
protected Map<Object, Object> readMap(TypeInformation<?> type, DBObject dbObject, ObjectPath path) {
protected Map<Object, Object> readMap(TypeInformation<?> type, Bson dbObject, ObjectPath path) {
Assert.notNull(dbObject, "DBObject must not be null!");
Assert.notNull(dbObject, "Document must not be null!");
Assert.notNull(path, "Object path must not be null!");
Class<?> mapType = typeMapper.readType(dbObject, type).getType();
@@ -945,8 +978,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
TypeInformation<?> valueType = type.getMapValueType();
Class<?> rawValueType = valueType == null ? null : valueType.getType();
Map<Object, Object> map = CollectionFactory.createMap(mapType, rawKeyType, dbObject.keySet().size());
Map<String, Object> sourceMap = dbObject.toMap();
Map<String, Object> sourceMap = asMap(dbObject);
Map<Object, Object> map = CollectionFactory.createMap(mapType, rawKeyType, sourceMap.keySet().size());
if (!DBRef.class.equals(rawValueType) && isCollectionOfDbRefWhereBulkFetchIsPossible(sourceMap.values())) {
bulkReadAndConvertDBRefMapIntoTarget(valueType, rawValueType, sourceMap, map);
@@ -966,11 +999,15 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
Object value = entry.getValue();
if (value instanceof DBObject) {
map.put(key, read(valueType, (DBObject) value, path));
if (value instanceof Document) {
map.put(key, read(valueType, (Document) value, path));
} else if (value instanceof BasicDBObject) {
map.put(key, read(valueType, (BasicDBObject) value, path));
} else if (value instanceof DBRef) {
map.put(key, DBRef.class.equals(rawValueType) ? value
: readAndConvertDBRef((DBRef) value, valueType, ObjectPath.ROOT, rawValueType));
} else if (value instanceof List) {
map.put(key, readCollectionOrArray(valueType, (List) value, path));
} else {
Class<?> valueClass = valueType == null ? null : valueType.getType();
map.put(key, getPotentiallyConvertedSimpleRead(value, valueClass));
@@ -980,6 +1017,55 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return map;
}
private Map<String, Object> asMap(Bson bson) {
if (bson instanceof Document) {
return (Document) bson;
}
if (bson instanceof DBObject) {
return ((DBObject) bson).toMap();
}
throw new IllegalArgumentException("o_O what's that? Cannot read values from " + bson.getClass());
}
private void addToMap(Bson bson, String key, Object value) {
if (bson instanceof Document) {
((Document) bson).put(key, value);
return;
}
if (bson instanceof DBObject) {
((DBObject) bson).put(key, value);
return;
}
throw new IllegalArgumentException("o_O what's that? Cannot add value to " + bson.getClass());
}
private void addAllToMap(Bson bson, Map value) {
if (bson instanceof Document) {
((Document) bson).putAll((Map) value);
return;
}
if (bson instanceof DBObject) {
((DBObject) bson).putAll((Map) value);
return;
}
throw new IllegalArgumentException("o_O what's that? Cannot add value to " + bson.getClass());
}
private void removeFromMap(Bson bson, String key) {
if (bson instanceof Document) {
((Document) bson).remove(key);
return;
}
if (bson instanceof DBObject) {
((DBObject) bson).removeField(key);
return;
}
throw new IllegalArgumentException("o_O what's that? Cannot add value to " + bson.getClass());
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.MongoWriter#convertToMongoType(java.lang.Object, org.springframework.data.util.TypeInformation)
@@ -1003,14 +1089,21 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
TypeInformation<?> typeHint = typeInformation;
if (obj instanceof BasicDBList) {
return maybeConvertList((BasicDBList) obj, typeHint);
if (obj instanceof List) {
return maybeConvertList((List) obj, typeHint);
}
if (obj instanceof Document) {
Document newValueDbo = new Document();
for (String vk : ((Document) obj).keySet()) {
Object o = ((Document) obj).get(vk);
newValueDbo.put(vk, convertToMongoType(o, typeHint));
}
return newValueDbo;
}
if (obj instanceof DBObject) {
DBObject newValueDbo = new BasicDBObject();
Document newValueDbo = new Document();
for (String vk : ((DBObject) obj).keySet()) {
Object o = ((DBObject) obj).get(vk);
@@ -1022,18 +1115,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
if (obj instanceof Map) {
Map<Object, Object> converted = new LinkedHashMap<Object, Object>();
for (Entry<Object, Object> entry : ((Map<Object, Object>) obj).entrySet()) {
TypeInformation<? extends Object> valueTypeHint = typeHint != null && typeHint.getMapValueType() != null
? typeHint.getMapValueType() : typeHint;
converted.put(getPotentiallyConvertedSimpleWrite(entry.getKey()).toString(),
convertToMongoType(entry.getValue(), valueTypeHint));
Document result = new Document();
for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) obj).entrySet()) {
result.put(entry.getKey().toString(), convertToMongoType(entry.getValue(), typeHint));
}
return new BasicDBObject(converted);
return result;
}
if (obj.getClass().isArray()) {
@@ -1044,7 +1131,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return maybeConvertList((Collection<?>) obj, typeHint);
}
DBObject newDbo = new BasicDBObject();
Document newDbo = new Document();
this.write(obj, newDbo);
if (typeInformation == null) {
@@ -1058,9 +1145,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return !obj.getClass().equals(typeInformation.getType()) ? newDbo : removeTypeInfo(newDbo, true);
}
public BasicDBList maybeConvertList(Iterable<?> source, TypeInformation<?> typeInformation) {
public List maybeConvertList(Iterable<?> source, TypeInformation<?> typeInformation) {
BasicDBList newDbl = new BasicDBList();
List newDbl = new ArrayList();
for (Object element : source) {
newDbl.add(convertToMongoType(element, typeInformation));
}
@@ -1077,11 +1164,11 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
*/
private Object removeTypeInfo(Object object, boolean recursively) {
if (!(object instanceof DBObject)) {
if (!(object instanceof Document)) {
return object;
}
DBObject dbObject = (DBObject) object;
Document dbObject = (Document) object;
String keyToRemove = null;
for (String key : dbObject.keySet()) {
@@ -1094,6 +1181,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
for (Object element : (BasicDBList) value) {
removeTypeInfo(element, recursively);
}
} else if (value instanceof List) {
for (Object element : (List) value) {
removeTypeInfo(element, recursively);
}
} else {
removeTypeInfo(value, recursively);
}
@@ -1110,7 +1201,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
if (keyToRemove != null) {
dbObject.removeField(keyToRemove);
dbObject.remove(keyToRemove);
}
return dbObject;
@@ -1118,13 +1209,13 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
/**
* {@link PropertyValueProvider} to evaluate a SpEL expression if present on the property or simply accesses the field
* of the configured source {@link DBObject}.
* of the configured source {@link Document}.
*
* @author Oliver Gierke
*/
private class MongoDbPropertyValueProvider implements PropertyValueProvider<MongoPersistentProperty> {
private final DBObjectAccessor source;
private final DocumentAccessor source;
private final SpELExpressionEvaluator evaluator;
private final ObjectPath path;
@@ -1136,12 +1227,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @param evaluator must not be {@literal null}.
* @param path can be {@literal null}.
*/
public MongoDbPropertyValueProvider(DBObject source, SpELExpressionEvaluator evaluator, ObjectPath path) {
public MongoDbPropertyValueProvider(Bson source, SpELExpressionEvaluator evaluator, ObjectPath path) {
Assert.notNull(source);
Assert.notNull(evaluator);
this.source = new DBObjectAccessor(source);
this.source = new DocumentAccessor(source);
this.evaluator = evaluator;
this.path = path;
}
@@ -1208,10 +1299,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return (T) conversionService.convert(value, rawType);
} else if (value instanceof DBRef) {
return potentiallyReadOrResolveDbRef((DBRef) value, type, path, rawType);
} else if (value instanceof BasicDBList) {
return (T) readCollectionOrArray(type, (BasicDBList) value, path);
} else if (value instanceof List) {
return (T) readCollectionOrArray(type, (List) value, path);
} else if (value instanceof Document) {
return (T) read(type, (Document) value, path);
} else if (value instanceof DBObject) {
return (T) read(type, (DBObject) value, path);
return (T) read(type, (BasicDBObject) value, path);
} else {
return (T) getPotentiallyConvertedSimpleRead(value, rawType);
}
@@ -1257,13 +1350,13 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return Collections.emptyList();
}
List<DBObject> referencedRawDocuments = dbrefs.size() == 1
List<Document> referencedRawDocuments = dbrefs.size() == 1
? Collections.singletonList(readRef(dbrefs.iterator().next())) : bulkReadRefs(dbrefs);
String collectionName = dbrefs.iterator().next().getCollectionName();
List<T> targeList = new ArrayList<T>(dbrefs.size());
for (DBObject document : referencedRawDocuments) {
for (Document document : referencedRawDocuments) {
if (document != null) {
maybeEmitEvent(new AfterLoadEvent<T>(document, (Class<T>) rawType, collectionName));
@@ -1297,7 +1390,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @param ref
* @return
*/
DBObject readRef(DBRef ref) {
Document readRef(DBRef ref) {
return dbRefResolver.fetch(ref);
}
@@ -1308,7 +1401,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @return never {@literal null}.
* @since 1.10
*/
List<DBObject> bulkReadRefs(List<DBRef> references) {
List<Document> bulkReadRefs(List<DBRef> references) {
return dbRefResolver.bulkFetch(references);
}

View File

@@ -15,26 +15,26 @@
*/
package org.springframework.data.mongodb.core.convert;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.data.convert.EntityConverter;
import org.springframework.data.convert.EntityReader;
import org.springframework.data.convert.TypeMapper;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import com.mongodb.DBObject;
/**
* Central Mongo specific converter interface which combines {@link MongoWriter} and {@link MongoReader}.
*
* @author Oliver Gierke
* @author Thomas Darimont
*/
public interface MongoConverter extends
EntityConverter<MongoPersistentEntity<?>, MongoPersistentProperty, Object, DBObject>, MongoWriter<Object>,
EntityReader<Object, DBObject> {
public interface MongoConverter
extends EntityConverter<MongoPersistentEntity<?>, MongoPersistentProperty, Object, Bson>, MongoWriter<Object>,
EntityReader<Object, Bson> {
/**
* Returns thw {@link TypeMapper} being used to write type information into {@link DBObject}s created with that
* Returns thw {@link TypeMapper} being used to write type information into {@link Document}s created with that
* converter.
*
* @return will never be {@literal null}.

View File

@@ -26,6 +26,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.bson.Document;
import org.bson.types.Code;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionFailedException;
@@ -41,8 +42,6 @@ import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBObject;
/**
@@ -75,10 +74,10 @@ abstract class MongoConverters {
converters.add(StringToBigIntegerConverter.INSTANCE);
converters.add(URLToStringConverter.INSTANCE);
converters.add(StringToURLConverter.INSTANCE);
converters.add(DBObjectToStringConverter.INSTANCE);
converters.add(DocumentToStringConverter.INSTANCE);
converters.add(TermToStringConverter.INSTANCE);
converters.add(NamedMongoScriptToDBObjectConverter.INSTANCE);
converters.add(DBObjectToNamedMongoScriptCoverter.INSTANCE);
converters.add(NamedMongoScriptToDocumentConverter.INSTANCE);
converters.add(DocumentToNamedMongoScriptCoverter.INSTANCE);
converters.add(CurrencyToStringConverter.INSTANCE);
converters.add(StringToCurrencyConverter.INSTANCE);
converters.add(AtomicIntegerToIntegerConverter.INSTANCE);
@@ -198,13 +197,21 @@ abstract class MongoConverters {
}
@ReadingConverter
public static enum DBObjectToStringConverter implements Converter<DBObject, String> {
public static enum DocumentToStringConverter implements Converter<Document, String> {
INSTANCE;
@Override
public String convert(DBObject source) {
return source == null ? null : source.toString();
public String convert(Document source) {
if (source == null) {
return null;
}
if (source instanceof Document) {
return ((Document) source).toJson();
}
return source.toString();
}
}
@@ -227,19 +234,27 @@ abstract class MongoConverters {
* @author Christoph Strobl
* @since 1.7
*/
public static enum DBObjectToNamedMongoScriptCoverter implements Converter<DBObject, NamedMongoScript> {
public static enum DocumentToNamedMongoScriptCoverter implements Converter<Document, NamedMongoScript> {
INSTANCE;
@Override
public NamedMongoScript convert(DBObject source) {
public NamedMongoScript convert(Document source) {
if (source == null) {
return null;
}
String id = source.get("_id").toString();
Object rawValue = source.get("value");
String id = null;
Object rawValue = null;
if (source instanceof Document) {
id = ((Document) source).get("_id").toString();
rawValue = ((Document) source).get("value");
} else if (source instanceof DBObject) {
id = ((DBObject) source).get("_id").toString();
rawValue = ((DBObject) source).get("value");
}
return new NamedMongoScript(id, ((Code) rawValue).getCode());
}
@@ -249,23 +264,23 @@ abstract class MongoConverters {
* @author Christoph Strobl
* @since 1.7
*/
public static enum NamedMongoScriptToDBObjectConverter implements Converter<NamedMongoScript, DBObject> {
public static enum NamedMongoScriptToDocumentConverter implements Converter<NamedMongoScript, Document> {
INSTANCE;
@Override
public DBObject convert(NamedMongoScript source) {
public Document convert(NamedMongoScript source) {
if (source == null) {
return new BasicDBObject();
return new Document();
}
BasicDBObjectBuilder builder = new BasicDBObjectBuilder();
Document document = new Document();
builder.append("_id", source.getName());
builder.append("value", new Code(source.getCode()));
document.put("_id", source.getName());
document.put("value", new Code(source.getCode()));
return builder.get();
return document;
}
}
@@ -320,7 +335,7 @@ abstract class MongoConverters {
* @since 1.9
*/
@WritingConverter
public static enum NumberToNumberConverterFactory implements ConverterFactory<Number, Number>,ConditionalConverter {
public static enum NumberToNumberConverterFactory implements ConverterFactory<Number, Number>, ConditionalConverter {
INSTANCE;

View File

@@ -27,6 +27,7 @@ import java.util.Set;
import java.util.Stack;
import java.util.regex.Pattern;
import org.bson.Document;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher.NullHandler;
import org.springframework.data.domain.ExampleMatcher.PropertyValueTransformer;
@@ -44,9 +45,6 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* @author Christoph Strobl
* @author Mark Paluch
@@ -71,13 +69,13 @@ public class MongoExampleMapper {
}
/**
* Returns the given {@link Example} as {@link DBObject} holding matching values extracted from
* Returns the given {@link Example} as {@link Document} holding matching values extracted from
* {@link Example#getProbe()}.
*
* @param example must not be {@literal null}.
* @return
*/
public DBObject getMappedExample(Example<?> example) {
public Document getMappedExample(Example<?> example) {
Assert.notNull(example, "Example must not be null!");
@@ -85,46 +83,47 @@ public class MongoExampleMapper {
}
/**
* Returns the given {@link Example} as {@link DBObject} holding matching values extracted from
* Returns the given {@link Example} as {@link Document} holding matching values extracted from
* {@link Example#getProbe()}.
*
* @param example must not be {@literal null}.
* @param entity must not be {@literal null}.
* @return
*/
public DBObject getMappedExample(Example<?> example, MongoPersistentEntity<?> entity) {
@SuppressWarnings({ "unchecked", "rawtypes" })
public Document getMappedExample(Example<?> example, MongoPersistentEntity<?> entity) {
Assert.notNull(example, "Example must not be null!");
Assert.notNull(entity, "MongoPersistentEntity must not be null!");
DBObject reference = (DBObject) converter.convertToMongoType(example.getProbe());
Document reference = (Document) converter.convertToMongoType(example.getProbe());
if (entity.hasIdProperty() && entity.getIdentifierAccessor(example.getProbe()).getIdentifier() == null) {
reference.removeField(entity.getIdProperty().getFieldName());
reference.remove(entity.getIdProperty().getFieldName());
}
ExampleMatcherAccessor matcherAccessor = new ExampleMatcherAccessor(example.getMatcher());
applyPropertySpecs("", reference, example.getProbeType(), matcherAccessor);
DBObject flattened = ObjectUtils.nullSafeEquals(NullHandler.INCLUDE, matcherAccessor.getNullHandler()) ? reference
: new BasicDBObject(SerializationUtils.flattenMap(reference));
DBObject result = example.getMatcher().isAllMatching() ? flattened : orConcatenate(flattened);
Document flattened = ObjectUtils.nullSafeEquals(NullHandler.INCLUDE, matcherAccessor.getNullHandler()) ? reference
: new Document(SerializationUtils.flattenMap(reference));
Document result = example.getMatcher().isAllMatching() ? flattened : orConcatenate(flattened);
this.converter.getTypeMapper().writeTypeRestrictions(result, getTypesToMatch(example));
return result;
}
private static DBObject orConcatenate(DBObject source) {
private static Document orConcatenate(Document source) {
List<DBObject> foo = new ArrayList<DBObject>(source.keySet().size());
List<Document> foo = new ArrayList<Document>(source.keySet().size());
for (String key : source.keySet()) {
foo.add(new BasicDBObject(key, source.get(key)));
foo.add(new Document(key, source.get(key)));
}
return new BasicDBObject("$or", foo);
return new Document("$or", foo);
}
private Set<Class<?>> getTypesToMatch(Example<?> example) {
@@ -187,14 +186,14 @@ public class MongoExampleMapper {
}
private void applyPropertySpecs(String path, DBObject source, Class<?> probeType,
private void applyPropertySpecs(String path, Document source, Class<?> probeType,
ExampleMatcherAccessor exampleSpecAccessor) {
if (!(source instanceof BasicDBObject)) {
if (!(source instanceof Document)) {
return;
}
Iterator<Map.Entry<String, Object>> iter = ((BasicDBObject) source).entrySet().iterator();
Iterator<Map.Entry<String, Object>> iter = ((Document) source).entrySet().iterator();
while (iter.hasNext()) {
@@ -240,8 +239,8 @@ public class MongoExampleMapper {
if (entry.getValue() instanceof String) {
applyStringMatcher(entry, stringMatcher, ignoreCase);
} else if (entry.getValue() instanceof BasicDBObject) {
applyPropertySpecs(propertyPath, (BasicDBObject) entry.getValue(), probeType, exampleSpecAccessor);
} else if (entry.getValue() instanceof Document) {
applyPropertySpecs(propertyPath, (Document) entry.getValue(), probeType, exampleSpecAccessor);
}
}
}
@@ -252,7 +251,7 @@ public class MongoExampleMapper {
private void applyStringMatcher(Map.Entry<String, Object> entry, StringMatcher stringMatcher, boolean ignoreCase) {
BasicDBObject dbo = new BasicDBObject();
Document dbo = new Document();
if (ObjectUtils.nullSafeEquals(StringMatcher.DEFAULT, stringMatcher)) {

View File

@@ -17,16 +17,16 @@ package org.springframework.data.mongodb.core.convert;
import java.util.Set;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.data.convert.TypeMapper;
import com.mongodb.DBObject;
/**
* Mongo-specific {@link TypeMapper} exposing that {@link DBObject}s might contain a type key.
* Mongo-specific {@link TypeMapper} exposing that {@link Document}s might contain a type key.
*
* @author Oliver Gierke
*/
public interface MongoTypeMapper extends TypeMapper<DBObject> {
public interface MongoTypeMapper extends TypeMapper<Bson> {
/**
* Returns whether the given key is the type key.
@@ -36,12 +36,12 @@ public interface MongoTypeMapper extends TypeMapper<DBObject> {
boolean isTypeKey(String key);
/**
* Writes type restrictions to the given {@link DBObject}. This usually results in an {@code $in}-clause to be
* Writes type restrictions to the given {@link Document}. This usually results in an {@code $in}-clause to be
* generated that restricts the type-key (e.g. {@code _class}) to be in the set of type aliases for the given
* {@code restrictedTypes}.
*
* @param result must not be {@literal null}
* @param restrictedTypes must not be {@literal null}
*/
void writeTypeRestrictions(DBObject result, Set<Class<?>> restrictedTypes);
void writeTypeRestrictions(Document result, Set<Class<?>> restrictedTypes);
}

View File

@@ -15,22 +15,22 @@
*/
package org.springframework.data.mongodb.core.convert;
import org.bson.conversions.Bson;
import org.springframework.data.convert.EntityWriter;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.TypeInformation;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
/**
* A MongoWriter is responsible for converting an object of type T to the native MongoDB representation DBObject.
* A MongoWriter is responsible for converting an object of type T to the native MongoDB representation Document.
*
* @param <T> the type of the object to convert to a DBObject
* @param <T> the type of the object to convert to a Document
* @author Mark Pollack
* @author Thomas Risberg
* @author Oliver Gierke
*/
public interface MongoWriter<T> extends EntityWriter<T, DBObject> {
public interface MongoWriter<T> extends EntityWriter<T, Bson> {
/**
* Converts the given object into one Mongo will be able to store natively. If the given object can already be stored

View File

@@ -23,14 +23,12 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.mongodb.DBObject;
/**
* A path of objects nested into each other. The type allows access to all parent objects currently in creation even
* when resolving more nested objects. This allows to avoid re-resolving object instances that are logically equivalent
* to already resolved ones.
* <p>
* An immutable ordered set of target objects for {@link DBObject} to {@link Object} conversions. Object paths can be
* An immutable ordered set of target objects for {@link Document} to {@link Object} conversions. Object paths can be
* constructed by the {@link #toObjectPath(Object)} method and extended via {@link #push(Object)}.
*
* @author Thomas Darimont

View File

@@ -23,6 +23,8 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConversionService;
@@ -41,6 +43,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty.PropertyToFieldNameConverter;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.util.BsonUtils;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
@@ -63,7 +66,7 @@ import com.mongodb.DBRef;
public class QueryMapper {
private static final List<String> DEFAULT_ID_NAMES = Arrays.asList("id", "_id");
private static final DBObject META_TEXT_SCORE = new BasicDBObject("$meta", "textScore");
private static final Document META_TEXT_SCORE = new Document("$meta", "textScore");
static final ClassTypeInformation<?> NESTED_DOCUMENT = ClassTypeInformation.from(NestedDocument.class);
private enum MetaMapping {
@@ -91,7 +94,7 @@ public class QueryMapper {
}
/**
* Replaces the property keys used in the given {@link DBObject} with the appropriate keys by using the
* Replaces the property keys used in the given {@link Document} with the appropriate keys by using the
* {@link PersistentEntity} metadata.
*
* @param query must not be {@literal null}.
@@ -99,21 +102,21 @@ public class QueryMapper {
* @return
*/
@SuppressWarnings("deprecation")
public DBObject getMappedObject(DBObject query, MongoPersistentEntity<?> entity) {
public Document getMappedObject(Bson query, MongoPersistentEntity<?> entity) {
if (isNestedKeyword(query)) {
return getMappedKeyword(new Keyword(query), entity);
}
DBObject result = new BasicDBObject();
Document result = new Document();
for (String key : query.keySet()) {
for (String key : BsonUtils.asMap(query).keySet()) {
// TODO: remove one once QueryMapper can work with Query instances directly
if (Query.isRestrictedTypeKey(key)) {
@SuppressWarnings("unchecked")
Set<Class<?>> restrictedTypes = (Set<Class<?>>) query.get(key);
Set<Class<?>> restrictedTypes = (Set<Class<?>>) BsonUtils.get(query, key);
this.converter.getTypeMapper().writeTypeRestrictions(result, restrictedTypes);
continue;
@@ -127,16 +130,16 @@ public class QueryMapper {
try {
Field field = createPropertyField(entity, key, mappingContext);
Entry<String, Object> entry = getMappedObjectForField(field, query.get(key));
Entry<String, Object> entry = getMappedObjectForField(field, BsonUtils.get(query, key));
result.put(entry.getKey(), entry.getValue());
} catch (InvalidPersistentPropertyPath invalidPathException) {
// in case the object has not already been mapped
if (!(query.get(key) instanceof DBObject)) {
if (!(BsonUtils.get(query, key) instanceof Document)) {
throw invalidPathException;
}
result.put(key, query.get(key));
result.put(key, BsonUtils.get(query, key));
}
}
@@ -152,13 +155,13 @@ public class QueryMapper {
* @return
* @since 1.6
*/
public DBObject getMappedSort(DBObject sortObject, MongoPersistentEntity<?> entity) {
public Document getMappedSort(Document sortObject, MongoPersistentEntity<?> entity) {
if (sortObject == null) {
return null;
}
DBObject mappedSort = getMappedObject(sortObject, entity);
Document mappedSort = getMappedObject(sortObject, entity);
mapMetaAttributes(mappedSort, entity, MetaMapping.WHEN_PRESENT);
return mappedSort;
}
@@ -172,14 +175,14 @@ public class QueryMapper {
* @return
* @since 1.6
*/
public DBObject getMappedFields(DBObject fieldsObject, MongoPersistentEntity<?> entity) {
public Document getMappedFields(Document fieldsObject, MongoPersistentEntity<?> entity) {
DBObject mappedFields = fieldsObject != null ? getMappedObject(fieldsObject, entity) : new BasicDBObject();
Document mappedFields = fieldsObject != null ? getMappedObject(fieldsObject, entity) : new Document();
mapMetaAttributes(mappedFields, entity, MetaMapping.FORCE);
return mappedFields.keySet().isEmpty() ? null : mappedFields;
}
private void mapMetaAttributes(DBObject source, MongoPersistentEntity<?> entity, MetaMapping metaMapping) {
private void mapMetaAttributes(Document source, MongoPersistentEntity<?> entity, MetaMapping metaMapping) {
if (entity == null || source == null) {
return;
@@ -188,14 +191,14 @@ public class QueryMapper {
if (entity.hasTextScoreProperty() && !MetaMapping.IGNORE.equals(metaMapping)) {
MongoPersistentProperty textScoreProperty = entity.getTextScoreProperty();
if (MetaMapping.FORCE.equals(metaMapping)
|| (MetaMapping.WHEN_PRESENT.equals(metaMapping) && source.containsField(textScoreProperty.getFieldName()))) {
|| (MetaMapping.WHEN_PRESENT.equals(metaMapping) && source.containsKey(textScoreProperty.getFieldName()))) {
source.putAll(getMappedTextScoreField(textScoreProperty));
}
}
}
private DBObject getMappedTextScoreField(MongoPersistentProperty property) {
return new BasicDBObject(property.getFieldName(), META_TEXT_SCORE);
private Document getMappedTextScoreField(MongoPersistentProperty property) {
return new Document(property.getFieldName(), META_TEXT_SCORE);
}
/**
@@ -211,7 +214,7 @@ public class QueryMapper {
Object value;
if (isNestedKeyword(rawValue) && !field.isIdField()) {
Keyword keyword = new Keyword((DBObject) rawValue);
Keyword keyword = new Keyword((Document) rawValue);
value = getMappedKeyword(field, keyword);
} else {
value = getMappedValue(field, rawValue);
@@ -232,33 +235,33 @@ public class QueryMapper {
}
/**
* Returns the given {@link DBObject} representing a keyword by mapping the keyword's value.
* Returns the given {@link Document} representing a keyword by mapping the keyword's value.
*
* @param keyword the {@link DBObject} representing a keyword (e.g. {@code $ne : … } )
* @param keyword the {@link Document} representing a keyword (e.g. {@code $ne : … } )
* @param entity
* @return
*/
protected DBObject getMappedKeyword(Keyword keyword, MongoPersistentEntity<?> entity) {
protected Document getMappedKeyword(Keyword keyword, MongoPersistentEntity<?> entity) {
// $or/$nor
if (keyword.isOrOrNor() || (keyword.hasIterableValue() && !keyword.isGeometry())) {
Iterable<?> conditions = keyword.getValue();
BasicDBList newConditions = new BasicDBList();
List newConditions = new ArrayList();
for (Object condition : conditions) {
newConditions.add(isDBObject(condition) ? getMappedObject((DBObject) condition, entity)
: convertSimpleOrDBObject(condition, entity));
newConditions.add(isDocument(condition) ? getMappedObject((Document) condition, entity)
: convertSimpleOrDocument(condition, entity));
}
return new BasicDBObject(keyword.getKey(), newConditions);
return new Document(keyword.getKey(), newConditions);
}
if (keyword.isSample()) {
return exampleMapper.getMappedExample(keyword.<Example<?>> getValue(), entity);
}
return new BasicDBObject(keyword.getKey(), convertSimpleOrDBObject(keyword.getValue(), entity));
return new Document(keyword.getKey(), convertSimpleOrDocument(keyword.getValue(), entity));
}
/**
@@ -268,7 +271,7 @@ public class QueryMapper {
* @param keyword
* @return
*/
protected DBObject getMappedKeyword(Field property, Keyword keyword) {
protected Document getMappedKeyword(Field property, Keyword keyword) {
boolean needsAssociationConversion = property.isAssociation() && !keyword.isExists();
Object value = keyword.getValue();
@@ -276,7 +279,7 @@ public class QueryMapper {
Object convertedValue = needsAssociationConversion ? convertAssociation(value, property)
: getMappedValue(property.with(keyword.getKey()), value);
return new BasicDBObject(keyword.key, convertedValue);
return new Document(keyword.key, convertedValue);
}
/**
@@ -294,7 +297,7 @@ public class QueryMapper {
if (isDBObject(value)) {
DBObject valueDbo = (DBObject) value;
DBObject resultDbo = new BasicDBObject(valueDbo.toMap());
Document resultDbo = new Document(valueDbo.toMap());
if (valueDbo.containsField("$in") || valueDbo.containsField("$nin")) {
String inKey = valueDbo.containsField("$in") ? "$in" : "$nin";
@@ -302,13 +305,31 @@ public class QueryMapper {
for (Object id : (Iterable<?>) valueDbo.get(inKey)) {
ids.add(convertId(id));
}
resultDbo.put(inKey, ids.toArray(new Object[ids.size()]));
resultDbo.put(inKey, ids);
} else if (valueDbo.containsField("$ne")) {
resultDbo.put("$ne", convertId(valueDbo.get("$ne")));
} else {
return getMappedObject(resultDbo, null);
}
return resultDbo;
}
else if (isDocument(value)) {
Document valueDbo = (Document) value;
Document resultDbo = new Document(valueDbo);
if (valueDbo.containsKey("$in") || valueDbo.containsKey("$nin")) {
String inKey = valueDbo.containsKey("$in") ? "$in" : "$nin";
List<Object> ids = new ArrayList<Object>();
for (Object id : (Iterable<?>) valueDbo.get(inKey)) {
ids.add(convertId(id));
}
resultDbo.put(inKey, ids);
} else if (valueDbo.containsKey("$ne")) {
resultDbo.put("$ne", convertId(valueDbo.get("$ne")));
} else {
return getMappedObject(resultDbo, null);
}
return resultDbo;
} else {
@@ -317,14 +338,14 @@ public class QueryMapper {
}
if (isNestedKeyword(value)) {
return getMappedKeyword(new Keyword((DBObject) value), documentField.getPropertyEntity());
return getMappedKeyword(new Keyword((Bson) value), documentField.getPropertyEntity());
}
if (isAssociationConversionNecessary(documentField, value)) {
return convertAssociation(value, documentField);
}
return convertSimpleOrDBObject(value, documentField.getPropertyEntity());
return convertSimpleOrDocument(value, documentField.getPropertyEntity());
}
/**
@@ -362,20 +383,28 @@ public class QueryMapper {
}
/**
* Retriggers mapping if the given source is a {@link DBObject} or simply invokes the
* Retriggers mapping if the given source is a {@link Document} or simply invokes the
*
* @param source
* @param entity
* @return
*/
protected Object convertSimpleOrDBObject(Object source, MongoPersistentEntity<?> entity) {
protected Object convertSimpleOrDocument(Object source, MongoPersistentEntity<?> entity) {
if (source instanceof List) {
return delegateConvertToMongoType(source, entity);
}
if (isDocument(source)) {
return getMappedObject((Document) source, entity);
}
if (source instanceof BasicDBList) {
return delegateConvertToMongoType(source, entity);
}
if (isDBObject(source)) {
return getMappedObject((DBObject) source, entity);
return getMappedObject((BasicDBObject) source, entity);
}
return delegateConvertToMongoType(source, entity);
@@ -406,7 +435,7 @@ public class QueryMapper {
*/
protected Object convertAssociation(Object source, MongoPersistentProperty property) {
if (property == null || source == null || source instanceof DBObject) {
if (property == null || source == null || source instanceof Document || source instanceof DBObject) {
return source;
}
@@ -425,8 +454,8 @@ public class QueryMapper {
}
if (property.isMap()) {
BasicDBObject result = new BasicDBObject();
DBObject dbObject = (DBObject) source;
Document result = new Document();
Document dbObject = (Document) source;
for (String key : dbObject.keySet()) {
result.put(key, createDbRefFor(dbObject.get(key), property));
}
@@ -437,11 +466,15 @@ public class QueryMapper {
}
/**
* Checks whether the given value is a {@link DBObject}.
* Checks whether the given value is a {@link Document}.
*
* @param value can be {@literal null}.
* @return
*/
protected final boolean isDocument(Object value) {
return value instanceof Document;
}
protected final boolean isDBObject(Object value) {
return value instanceof DBObject;
}
@@ -504,19 +537,18 @@ public class QueryMapper {
}
/**
* Returns whether the given {@link Object} is a keyword, i.e. if it's a {@link DBObject} with a keyword key.
* Returns whether the given {@link Object} is a keyword, i.e. if it's a {@link Document} with a keyword key.
*
* @param candidate
* @return
*/
protected boolean isNestedKeyword(Object candidate) {
if (!(candidate instanceof BasicDBObject)) {
if (!(candidate instanceof Document)) {
return false;
}
BasicDBObject dbObject = (BasicDBObject) candidate;
Set<String> keys = dbObject.keySet();
Set<String> keys = BsonUtils.asMap((Bson) candidate).keySet();
if (keys.size() != 1) {
return false;
@@ -548,18 +580,18 @@ public class QueryMapper {
private final String key;
private final Object value;
public Keyword(DBObject source, String key) {
public Keyword(Bson source, String key) {
this.key = key;
this.value = source.get(key);
this.value = BsonUtils.get(source, key);
}
public Keyword(DBObject dbObject) {
public Keyword(Bson dbObject) {
Set<String> keys = dbObject.keySet();
Assert.isTrue(keys.size() == 1, "Can only use a single value DBObject!");
Set<String> keys = BsonUtils.asMap(dbObject).keySet();
Assert.isTrue(keys.size() == 1, "Can only use a single value Document!");
this.key = keys.iterator().next();
this.value = dbObject.get(key);
this.value = BsonUtils.get(dbObject, key);
}
/**

View File

@@ -20,12 +20,13 @@ import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.bson.Document;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.util.Assert;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
import com.mongodb.client.model.Filters;
/**
* {@link ReflectiveDBRefResolver} provides reflective access to {@link DBRef} API that is not consistently available
@@ -51,16 +52,18 @@ class ReflectiveDBRefResolver {
* @param ref must not be {@literal null}.
* @return the document that this references.
*/
public static DBObject fetch(MongoDbFactory factory, DBRef ref) {
public static Document fetch(MongoDbFactory factory, DBRef ref) {
Assert.notNull(ref, "DBRef to fetch must not be null!");
if (isMongo3Driver()) {
Assert.notNull(factory, "DbFactory to fetch DB from must not be null!");
return factory.getDb().getCollection(ref.getCollectionName()).findOne(ref.getId());
return factory.getDb().getCollection(ref.getCollectionName(), Document.class).find(Filters.eq("_id", ref.getId()))
.first();
}
return (DBObject) invokeMethod(FETCH_METHOD, ref);
return (Document) invokeMethod(FETCH_METHOD, ref);
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.convert;
import java.util.Map.Entry;
import org.bson.Document;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.context.MappingContext;
@@ -28,9 +29,6 @@ import org.springframework.data.mongodb.core.query.Update.Modifiers;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* A subclass of {@link QueryMapper} that retains type information on the mongo types.
*
@@ -73,8 +71,8 @@ public class UpdateMapper extends QueryMapper {
@Override
protected Entry<String, Object> getMappedObjectForField(Field field, Object rawValue) {
if (isDBObject(rawValue)) {
return createMapEntry(field, convertSimpleOrDBObject(rawValue, field.getPropertyEntity()));
if (isDocument(rawValue)) {
return createMapEntry(field, convertSimpleOrDocument(rawValue, field.getPropertyEntity()));
}
if (isQuery(rawValue)) {
@@ -98,10 +96,10 @@ public class UpdateMapper extends QueryMapper {
} else if (rawValue instanceof Modifiers) {
DBObject modificationOperations = new BasicDBObject();
Document modificationOperations = new Document();
for (Modifier modifier : ((Modifiers) rawValue).getModifiers()) {
modificationOperations.putAll(getMappedValue(field, modifier).toMap());
modificationOperations.putAll(getMappedValue(field, modifier));
}
value = modificationOperations;
@@ -129,12 +127,12 @@ public class UpdateMapper extends QueryMapper {
return value instanceof Query;
}
private DBObject getMappedValue(Field field, Modifier modifier) {
private Document getMappedValue(Field field, Modifier modifier) {
TypeInformation<?> typeHint = field == null ? ClassTypeInformation.OBJECT : field.getTypeHint();
Object value = converter.convertToMongoType(modifier.getValue(), typeHint);
return new BasicDBObject(modifier.getKey(), value);
return new Document(modifier.getKey(), value);
}
private TypeInformation<?> getTypeHintForEntity(Object source, MongoPersistentEntity<?> entity) {

View File

@@ -15,11 +15,11 @@
*/
package org.springframework.data.mongodb.core.convert;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import com.mongodb.DBObject;
/**
* Internal API to trigger the resolution of properties.
*
@@ -28,7 +28,7 @@ import com.mongodb.DBObject;
interface ValueResolver {
/**
* Resolves the value for the given {@link MongoPersistentProperty} within the given {@link DBObject} using the given
* Resolves the value for the given {@link MongoPersistentProperty} within the given {@link Document} using the given
* {@link SpELExpressionEvaluator} and {@link ObjectPath}.
*
* @param prop
@@ -37,6 +37,5 @@ interface ValueResolver {
* @param parent
* @return
*/
Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, SpELExpressionEvaluator evaluator,
ObjectPath parent);
Object getValueInternal(MongoPersistentProperty prop, Bson dbo, SpELExpressionEvaluator evaluator, ObjectPath parent);
}

View File

@@ -15,11 +15,9 @@
*/
package org.springframework.data.mongodb.core.index;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Index definition to span multiple keys.
*
@@ -28,14 +26,14 @@ import com.mongodb.DBObject;
*/
public class CompoundIndexDefinition extends Index {
private DBObject keys;
private Document keys;
/**
* Creates a new {@link CompoundIndexDefinition} for the given keys.
*
* @param keys must not be {@literal null}.
*/
public CompoundIndexDefinition(DBObject keys) {
public CompoundIndexDefinition(Document keys) {
Assert.notNull(keys, "Keys must not be null!");
this.keys = keys;
@@ -46,9 +44,9 @@ public class CompoundIndexDefinition extends Index {
* @see org.springframework.data.mongodb.core.index.Index#getIndexKeys()
*/
@Override
public DBObject getIndexKeys() {
public Document getIndexKeys() {
BasicDBObject dbo = new BasicDBObject();
Document dbo = new Document();
dbo.putAll(this.keys);
dbo.putAll(super.getIndexKeys());
return dbo;

View File

@@ -15,12 +15,10 @@
*/
package org.springframework.data.mongodb.core.index;
import org.bson.Document;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Value object to capture data to create a geo index.
*
@@ -119,9 +117,9 @@ public class GeospatialIndex implements IndexDefinition {
return this;
}
public DBObject getIndexKeys() {
public Document getIndexKeys() {
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
switch (type) {
@@ -148,13 +146,13 @@ public class GeospatialIndex implements IndexDefinition {
return dbo;
}
public DBObject getIndexOptions() {
public Document getIndexOptions() {
if (!StringUtils.hasText(name) && min == null && max == null && bucketSize == null) {
return null;
}
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
if (StringUtils.hasText(name)) {
dbo.put("name", name);
}

View File

@@ -20,14 +20,12 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.bson.Document;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.query.Order;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* @author Oliver Gierke
* @author Christoph Strobl
@@ -180,9 +178,9 @@ public class Index implements IndexDefinition {
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.index.IndexDefinition#getIndexKeys()
*/
public DBObject getIndexKeys() {
public Document getIndexKeys() {
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
for (Entry<String, Direction> entry : fieldSpec.entrySet()) {
dbo.put(entry.getKey(), Direction.ASC.equals(entry.getValue()) ? 1 : -1);
@@ -191,9 +189,9 @@ public class Index implements IndexDefinition {
return dbo;
}
public DBObject getIndexOptions() {
public Document getIndexOptions() {
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
if (StringUtils.hasText(name)) {
dbo.put("name", name);
}

View File

@@ -16,7 +16,7 @@
package org.springframework.data.mongodb.core.index;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
@@ -24,7 +24,7 @@ import com.mongodb.DBObject;
*/
public interface IndexDefinition {
DBObject getIndexKeys();
Document getIndexKeys();
DBObject getIndexOptions();
Document getIndexOptions();
}

View File

@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.index;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,8 +35,9 @@ import org.springframework.data.mongodb.util.MongoDbErrorCodes;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.IndexOptions;
/**
* Component that inspects {@link MongoPersistentEntity} instances contained in the given {@link MongoMappingContext}
@@ -139,14 +141,67 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
try {
mongoDbFactory.getDb().getCollection(indexDefinition.getCollection()).createIndex(indexDefinition.getIndexKeys(),
indexDefinition.getIndexOptions());
IndexOptions ops = new IndexOptions();
if (indexDefinition.getIndexOptions() != null) {
org.bson.Document indexOptions = indexDefinition.getIndexOptions();
if (indexOptions.containsKey("name")) {
ops = ops.name(indexOptions.get("name").toString());
}
if (indexOptions.containsKey("unique")) {
ops = ops.unique((Boolean) indexOptions.get("unique"));
}
// if(indexOptions.containsField("dropDuplicates")) {
// ops = ops.((boolean)indexOptions.get("dropDuplicates"));
// }
if (indexOptions.containsKey("sparse")) {
ops = ops.sparse((Boolean) indexOptions.get("sparse"));
}
if (indexOptions.containsKey("background")) {
ops = ops.background((Boolean) indexOptions.get("background"));
}
if (indexOptions.containsKey("expireAfterSeconds")) {
ops = ops.expireAfter((Long) indexOptions.get("expireAfterSeconds"), TimeUnit.SECONDS);
}
if (indexOptions.containsKey("min")) {
ops = ops.min(((Number) indexOptions.get("min")).doubleValue());
}
if (indexOptions.containsKey("max")) {
ops = ops.max(((Number) indexOptions.get("max")).doubleValue());
}
if (indexOptions.containsKey("bits")) {
ops = ops.bits((Integer) indexOptions.get("bits"));
}
if (indexOptions.containsKey("bucketSize")) {
ops = ops.bucketSize(((Number) indexOptions.get("bucketSize")).doubleValue());
}
if (indexOptions.containsKey("default_language")) {
ops = ops.defaultLanguage(indexOptions.get("default_language").toString());
}
if (indexOptions.containsKey("language_override")) {
ops = ops.languageOverride(indexOptions.get("language_override").toString());
}
if (indexOptions.containsKey("weights")) {
ops = ops.weights((org.bson.Document) indexOptions.get("weights"));
}
for (String key : indexOptions.keySet()) {
if (ObjectUtils.nullSafeEquals("2dsphere", indexOptions.get(key))) {
ops = ops.sphereVersion(2);
}
}
}
mongoDbFactory.getDb().getCollection(indexDefinition.getCollection(), Document.class)
.createIndex(indexDefinition.getIndexKeys(), ops);
} catch (MongoException ex) {
if (MongoDbErrorCodes.isDataIntegrityViolationCode(ex.getCode())) {
DBObject existingIndex = fetchIndexInformation(indexDefinition);
org.bson.Document existingIndex = fetchIndexInformation(indexDefinition);
String message = "Cannot create index for '%s' in collection '%s' with keys '%s' and options '%s'.";
if (existingIndex != null) {
@@ -175,7 +230,7 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
return this.mappingContext.equals(context);
}
private DBObject fetchIndexInformation(IndexDefinitionHolder indexDefinition) {
private org.bson.Document fetchIndexInformation(IndexDefinitionHolder indexDefinition) {
if (indexDefinition == null) {
return null;
@@ -185,7 +240,12 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
Object indexNameToLookUp = indexDefinition.getIndexOptions().get("name");
for (DBObject index : mongoDbFactory.getDb().getCollection(indexDefinition.getCollection()).getIndexInfo()) {
MongoCursor<org.bson.Document> cursor = mongoDbFactory.getDb().getCollection(indexDefinition.getCollection())
.listIndexes(org.bson.Document.class).iterator();
while (cursor.hasNext()) {
org.bson.Document index = cursor.next();
if (ObjectUtils.nullSafeEquals(indexNameToLookUp, index.get("name"))) {
return index;
}

View File

@@ -16,8 +16,10 @@
package org.springframework.data.mongodb.core.index;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -41,13 +43,9 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
/**
* {@link IndexResolver} implementation inspecting {@link MongoPersistentEntity} for {@link MongoPersistentEntity} to be
* indexed. <br />
@@ -203,8 +201,22 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
private Collection<? extends IndexDefinitionHolder> potentiallyCreateTextIndexDefinition(
MongoPersistentEntity<?> root) {
TextIndexDefinitionBuilder indexDefinitionBuilder = new TextIndexDefinitionBuilder()
.named(root.getType().getSimpleName() + "_TextIndex");
String name = root.getType().getSimpleName() + "_TextIndex";
if (name.getBytes().length > 127) {
String[] args = ClassUtils.getShortNameAsProperty(root.getType()).split("\\.");
name = "";
Iterator<String> it = Arrays.asList(args).iterator();
while (it.hasNext()) {
if (!it.hasNext()) {
name += it.next() + "_TextIndex";
} else {
name += (it.next().charAt(0) + ".");
}
}
}
TextIndexDefinitionBuilder indexDefinitionBuilder = new TextIndexDefinitionBuilder().named(name);
if (StringUtils.hasText(root.getLanguage())) {
indexDefinitionBuilder.withDefaultLanguage(root.getLanguage());
@@ -335,27 +347,27 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
return new IndexDefinitionHolder(dotPath, indexDefinition, collection);
}
private DBObject resolveCompoundIndexKeyFromStringDefinition(String dotPath, String keyDefinitionString) {
private org.bson.Document resolveCompoundIndexKeyFromStringDefinition(String dotPath, String keyDefinitionString) {
if (!StringUtils.hasText(dotPath) && !StringUtils.hasText(keyDefinitionString)) {
throw new InvalidDataAccessApiUsageException("Cannot create index on root level for empty keys.");
}
if (!StringUtils.hasText(keyDefinitionString)) {
return new BasicDBObject(dotPath, 1);
return new org.bson.Document(dotPath, 1);
}
DBObject dbo = (DBObject) JSON.parse(keyDefinitionString);
org.bson.Document dbo = org.bson.Document.parse(keyDefinitionString);
if (!StringUtils.hasText(dotPath)) {
return dbo;
}
BasicDBObjectBuilder dboBuilder = new BasicDBObjectBuilder();
org.bson.Document document = new org.bson.Document();
for (String key : dbo.keySet()) {
dboBuilder.add(dotPath + "." + key, dbo.get(key));
document.put(dotPath + "." + key, dbo.get(key));
}
return dboBuilder.get();
return document;
}
/**
@@ -667,7 +679,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
* @see org.springframework.data.mongodb.core.index.IndexDefinition#getIndexKeys()
*/
@Override
public DBObject getIndexKeys() {
public org.bson.Document getIndexKeys() {
return indexDefinition.getIndexKeys();
}
@@ -676,7 +688,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
* @see org.springframework.data.mongodb.core.index.IndexDefinition#getIndexOptions()
*/
@Override
public DBObject getIndexOptions() {
public org.bson.Document getIndexOptions() {
return indexDefinition.getIndexOptions();
}
}

View File

@@ -19,14 +19,12 @@ import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import org.bson.Document;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* {@link IndexDefinition} to span multiple keys for text search.
*
@@ -90,9 +88,9 @@ public class TextIndexDefinition implements IndexDefinition {
* @see org.springframework.data.mongodb.core.index.IndexDefinition#getIndexKeys()
*/
@Override
public DBObject getIndexKeys() {
public Document getIndexKeys() {
DBObject keys = new BasicDBObject();
Document keys = new Document();
for (TextIndexedFieldSpec fieldSpec : fieldSpecs) {
keys.put(fieldSpec.fieldname, "text");
}
@@ -105,9 +103,9 @@ public class TextIndexDefinition implements IndexDefinition {
* @see org.springframework.data.mongodb.core.index.IndexDefinition#getIndexOptions()
*/
@Override
public DBObject getIndexOptions() {
public Document getIndexOptions() {
DBObject options = new BasicDBObject();
Document options = new Document();
if (StringUtils.hasText(name)) {
options.put("name", name);
}
@@ -115,7 +113,7 @@ public class TextIndexDefinition implements IndexDefinition {
options.put("default_language", defaultLanguage);
}
BasicDBObject weightsDbo = new BasicDBObject();
Document weightsDbo = new Document();
for (TextIndexedFieldSpec fieldSpec : fieldSpecs) {
if (fieldSpec.isWeighted()) {
weightsDbo.put(fieldSpec.getFieldname(), fieldSpec.getWeight());
@@ -288,8 +286,8 @@ public class TextIndexDefinition implements IndexDefinition {
public TextIndexDefinitionBuilder onField(String fieldname, Float weight) {
if (this.instance.fieldSpecs.contains(ALL_FIELDS)) {
throw new InvalidDataAccessApiUsageException(String.format("Cannot add %s to field spec for all fields.",
fieldname));
throw new InvalidDataAccessApiUsageException(
String.format("Cannot add %s to field spec for all fields.", fieldname));
}
this.instance.fieldSpecs.add(new TextIndexedFieldSpec(fieldname, weight));
@@ -318,8 +316,8 @@ public class TextIndexDefinition implements IndexDefinition {
public TextIndexDefinitionBuilder withLanguageOverride(String fieldname) {
if (StringUtils.hasText(this.instance.languageOverride)) {
throw new InvalidDataAccessApiUsageException(String.format(
"Cannot set language override on %s as it is already defined on %s.", fieldname,
throw new InvalidDataAccessApiUsageException(
String.format("Cannot set language override on %s as it is already defined on %s.", fieldname,
this.instance.languageOverride));
}

View File

@@ -33,8 +33,6 @@ import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.util.StringUtils;
import com.mongodb.DBObject;
/**
* MongoDB specific {@link org.springframework.data.mapping.MongoPersistentProperty} implementation.
*
@@ -43,8 +41,8 @@ import com.mongodb.DBObject;
* @author Thomas Darimont
* @author Christoph Strobl
*/
public class BasicMongoPersistentProperty extends AnnotationBasedPersistentProperty<MongoPersistentProperty> implements
MongoPersistentProperty {
public class BasicMongoPersistentProperty extends AnnotationBasedPersistentProperty<MongoPersistentProperty>
implements MongoPersistentProperty {
private static final Logger LOG = LoggerFactory.getLogger(BasicMongoPersistentProperty.class);
@@ -114,7 +112,7 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
}
/**
* Returns the key to be used to store the value of the property inside a Mongo {@link DBObject}.
* Returns the key to be used to store the value of the property inside a Mongo {@link org.bson.Document}.
*
* @return
*/
@@ -160,7 +158,8 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
private String getAnnotatedFieldName() {
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(
org.springframework.data.mongodb.core.mapping.Field.class);
if (annotation != null && StringUtils.hasText(annotation.value())) {
return annotation.value();
@@ -174,7 +173,8 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#getFieldOrder()
*/
public int getFieldOrder() {
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(
org.springframework.data.mongodb.core.mapping.Field.class);
return annotation != null ? annotation.order() : Integer.MAX_VALUE;
}

View File

@@ -22,12 +22,12 @@ import java.util.Set;
import java.util.UUID;
import java.util.regex.Pattern;
import org.bson.BsonObjectId;
import org.bson.types.Binary;
import org.bson.types.CodeWScope;
import org.bson.types.ObjectId;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
/**
@@ -49,8 +49,9 @@ public abstract class MongoSimpleTypes {
Set<Class<?>> simpleTypes = new HashSet<Class<?>>();
simpleTypes.add(DBRef.class);
simpleTypes.add(ObjectId.class);
simpleTypes.add(BsonObjectId.class);
simpleTypes.add(CodeWScope.class);
simpleTypes.add(DBObject.class);
simpleTypes.add(org.bson.Document.class);
simpleTypes.add(Pattern.class);
simpleTypes.add(Binary.class);
simpleTypes.add(UUID.class);
@@ -60,6 +61,5 @@ public abstract class MongoSimpleTypes {
private static final Set<Class<?>> MONGO_SIMPLE_TYPES;
public static final SimpleTypeHolder HOLDER = new SimpleTypeHolder(MONGO_SIMPLE_TYPES, true);
private MongoSimpleTypes() {
}
private MongoSimpleTypes() {}
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb.core.mapping.event;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* Base class for delete events.
@@ -23,32 +23,32 @@ import com.mongodb.DBObject;
* @author Martin Baumgartner
* @author Christoph Strobl
*/
public abstract class AbstractDeleteEvent<T> extends MongoMappingEvent<DBObject> {
public abstract class AbstractDeleteEvent<T> extends MongoMappingEvent<Document> {
private static final long serialVersionUID = 1L;
private final Class<T> type;
/**
* Creates a new {@link AbstractDeleteEvent} for the given {@link DBObject} and type.
* Creates a new {@link AbstractDeleteEvent} for the given {@link Document} and type.
*
* @param dbo must not be {@literal null}.
* @param type can be {@literal null}.
* @deprecated since 1.8. Please use {@link #AbstractDeleteEvent(DBObject, Class, String)}.
* @deprecated since 1.8. Please use {@link #AbstractDeleteEvent(Document, Class, String)}.
*/
@Deprecated
public AbstractDeleteEvent(DBObject dbo, Class<T> type) {
public AbstractDeleteEvent(Document dbo, Class<T> type) {
this(dbo, type, null);
}
/**
* Creates a new {@link AbstractDeleteEvent} for the given {@link DBObject} and type.
* Creates a new {@link AbstractDeleteEvent} for the given {@link Document} and type.
*
* @param dbo must not be {@literal null}.
* @param type can be {@literal null}.
* @param collectionName can be {@literal null}.
* @since 1.8
*/
public AbstractDeleteEvent(DBObject dbo, Class<T> type, String collectionName) {
public AbstractDeleteEvent(Document dbo, Class<T> type, String collectionName) {
super(dbo, dbo, collectionName);
this.type = type;

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.mongodb.core.mapping.event;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
@@ -115,7 +116,7 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
public void onBeforeSave(BeforeSaveEvent<E> event) {
if (LOG.isDebugEnabled()) {
LOG.debug("onBeforeSave({}, {})", event.getSource(), event.getDBObject());
LOG.debug("onBeforeSave({}, {})", event.getSource(), event.getDocument());
}
}
@@ -128,7 +129,7 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
public void onAfterSave(AfterSaveEvent<E> event) {
if (LOG.isDebugEnabled()) {
LOG.debug("onAfterSave({}, {})", event.getSource(), event.getDBObject());
LOG.debug("onAfterSave({}, {})", event.getSource(), event.getDocument());
}
}
@@ -141,7 +142,7 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
public void onAfterLoad(AfterLoadEvent<E> event) {
if (LOG.isDebugEnabled()) {
LOG.debug("onAfterLoad({})", event.getDBObject());
LOG.debug("onAfterLoad({})", event.getDocument());
}
}
@@ -154,7 +155,7 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
public void onAfterConvert(AfterConvertEvent<E> event) {
if (LOG.isDebugEnabled()) {
LOG.debug("onAfterConvert({}, {})", event.getDBObject(), event.getSource());
LOG.debug("onAfterConvert({}, {})", event.getDocument(), event.getSource());
}
}
@@ -167,7 +168,7 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
public void onAfterDelete(AfterDeleteEvent<E> event) {
if (LOG.isDebugEnabled()) {
LOG.debug("onAfterDelete({})", event.getDBObject());
LOG.debug("onAfterDelete({})", event.getDocument());
}
}
@@ -180,7 +181,7 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
public void onBeforeDelete(BeforeDeleteEvent<E> event) {
if (LOG.isDebugEnabled()) {
LOG.debug("onBeforeDelete({})", event.getDBObject());
LOG.debug("onBeforeDelete({})", event.getDocument());
}
}
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb.core.mapping.event;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* {@link MongoMappingEvent} thrown after convert of a document.
@@ -32,10 +32,10 @@ public class AfterConvertEvent<E> extends MongoMappingEvent<E> {
*
* @param dbo can be {@literal null}.
* @param source must not be {@literal null}.
* @deprecated since 1.8. Please use {@link #AfterConvertEvent(DBObject, Object, String)}.
* @deprecated since 1.8. Please use {@link #AfterConvertEvent(Document, Object, String)}.
*/
@Deprecated
public AfterConvertEvent(DBObject dbo, E source) {
public AfterConvertEvent(Document dbo, E source) {
this(dbo, source, null);
}
@@ -47,7 +47,7 @@ public class AfterConvertEvent<E> extends MongoMappingEvent<E> {
* @param collectionName can be {@literal null}.
* @since 1.8
*/
public AfterConvertEvent(DBObject dbo, E source, String collectionName) {
public AfterConvertEvent(Document dbo, E source, String collectionName) {
super(source, dbo, collectionName);
}

View File

@@ -15,10 +15,10 @@
*/
package org.springframework.data.mongodb.core.mapping.event;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* Event being thrown after a single or a set of documents has/have been deleted. The {@link DBObject} held in the event
* Event being thrown after a single or a set of documents has/have been deleted. The {@link Document} held in the event
* will be the query document <em>after</am> it has been mapped onto the domain type handled.
*
* @author Martin Baumgartner
@@ -29,26 +29,26 @@ public class AfterDeleteEvent<T> extends AbstractDeleteEvent<T> {
private static final long serialVersionUID = 1L;
/**
* Creates a new {@link AfterDeleteEvent} for the given {@link DBObject} and type.
* Creates a new {@link AfterDeleteEvent} for the given {@link Document} and type.
*
* @param dbo must not be {@literal null}.
* @param type can be {@literal null}.
* @deprecated since 1.8. Please use {@link #AfterDeleteEvent(DBObject, Class, String)}.
* @deprecated since 1.8. Please use {@link #AfterDeleteEvent(Document, Class, String)}.
*/
@Deprecated
public AfterDeleteEvent(DBObject dbo, Class<T> type) {
public AfterDeleteEvent(Document dbo, Class<T> type) {
this(dbo, type, null);
}
/**
* Creates a new {@link AfterDeleteEvent} for the given {@link DBObject}, type and collectionName.
* Creates a new {@link AfterDeleteEvent} for the given {@link Document}, type and collectionName.
*
* @param dbo must not be {@literal null}.
* @param type can be {@literal null}.
* @param collectionName can be {@literal null}.
* @since 1.8
*/
public AfterDeleteEvent(DBObject dbo, Class<T> type, String collectionName) {
public AfterDeleteEvent(Document dbo, Class<T> type, String collectionName) {
super(dbo, type, collectionName);
}
}

View File

@@ -16,44 +16,43 @@
package org.springframework.data.mongodb.core.mapping.event;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.DBObject;
/**
* Event to be triggered after loading {@link DBObject}s to be mapped onto a given type.
* Event to be triggered after loading {@link Document}s to be mapped onto a given type.
*
* @author Oliver Gierke
* @author Jon Brisbin
* @author Christoph Leiter
* @author Christoph Strobl
*/
public class AfterLoadEvent<T> extends MongoMappingEvent<DBObject> {
public class AfterLoadEvent<T> extends MongoMappingEvent<Document> {
private static final long serialVersionUID = 1L;
private final Class<T> type;
/**
* Creates a new {@link AfterLoadEvent} for the given {@link DBObject} and type.
* Creates a new {@link AfterLoadEvent} for the given {@link Document} and type.
*
* @param dbo must not be {@literal null}.
* @param type can be {@literal null}.
* @deprecated since 1.8. Please use {@link #AfterLoadEvent(DBObject, Class, String)}.
* @deprecated since 1.8. Please use {@link #AfterLoadEvent(Document, Class, String)}.
*/
@Deprecated
public AfterLoadEvent(DBObject dbo, Class<T> type) {
public AfterLoadEvent(Document dbo, Class<T> type) {
this(dbo, type, null);
}
/**
* Creates a new {@link AfterLoadEvent} for the given {@link DBObject}, type and collectionName.
* Creates a new {@link AfterLoadEvent} for the given {@link Document}, type and collectionName.
*
* @param dbo must not be {@literal null}.
* @param type must not be {@literal null}.
* @param collectionName can be {@literal null}.
* @since 1.8
*/
public AfterLoadEvent(DBObject dbo, Class<T> type, String collectionName) {
public AfterLoadEvent(Document dbo, Class<T> type, String collectionName) {
super(dbo, dbo, collectionName);

View File

@@ -16,7 +16,7 @@
package org.springframework.data.mongodb.core.mapping.event;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* {@link MongoMappingEvent} triggered after save of a document.
@@ -33,10 +33,10 @@ public class AfterSaveEvent<E> extends MongoMappingEvent<E> {
*
* @param source must not be {@literal null}.
* @param dbo can be {@literal null}.
* @deprecated since 1.8. Please use {@link #AfterSaveEvent(Object, DBObject, String)}.
* @deprecated since 1.8. Please use {@link #AfterSaveEvent(Object, Document, String)}.
*/
@Deprecated
public AfterSaveEvent(E source, DBObject dbo) {
public AfterSaveEvent(E source, Document dbo) {
super(source, dbo);
}
@@ -48,7 +48,7 @@ public class AfterSaveEvent<E> extends MongoMappingEvent<E> {
* @param collectionName can be {@literal null}.
* @since 1.8
*/
public AfterSaveEvent(E source, DBObject dbo, String collectionName) {
public AfterSaveEvent(E source, Document dbo, String collectionName) {
super(source, dbo, collectionName);
}

View File

@@ -15,10 +15,10 @@
*/
package org.springframework.data.mongodb.core.mapping.event;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* Event being thrown before a document is deleted. The {@link DBObject} held in the event will represent the query
* Event being thrown before a document is deleted. The {@link Document} held in the event will represent the query
* document <em>before</em> being mapped based on the domain class handled.
*
* @author Martin Baumgartner
@@ -29,26 +29,26 @@ public class BeforeDeleteEvent<T> extends AbstractDeleteEvent<T> {
private static final long serialVersionUID = -2627547705679734497L;
/**
* Creates a new {@link BeforeDeleteEvent} for the given {@link DBObject} and type.
* Creates a new {@link BeforeDeleteEvent} for the given {@link Document} and type.
*
* @param dbo must not be {@literal null}.
* @param type can be {@literal null}.
* @deprecated since 1.8. Please use {@link #BeforeDeleteEvent(DBObject, Class, String)}.
* @deprecated since 1.8. Please use {@link #BeforeDeleteEvent(Document, Class, String)}.
*/
@Deprecated
public BeforeDeleteEvent(DBObject dbo, Class<T> type) {
public BeforeDeleteEvent(Document dbo, Class<T> type) {
this(dbo, type, null);
}
/**
* Creates a new {@link BeforeDeleteEvent} for the given {@link DBObject}, type and collectionName.
* Creates a new {@link BeforeDeleteEvent} for the given {@link Document}, type and collectionName.
*
* @param dbo must not be {@literal null}.
* @param type can be {@literal null}.
* @param collectionName can be {@literal null}.
* @since 1.8
*/
public BeforeDeleteEvent(DBObject dbo, Class<T> type, String collectionName) {
public BeforeDeleteEvent(Document dbo, Class<T> type, String collectionName) {
super(dbo, type, collectionName);
}
}

View File

@@ -16,7 +16,7 @@
package org.springframework.data.mongodb.core.mapping.event;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* {@link MongoMappingEvent} triggered before save of a document.
@@ -33,10 +33,10 @@ public class BeforeSaveEvent<E> extends MongoMappingEvent<E> {
*
* @param source must not be {@literal null}.
* @param dbo can be {@literal null}.
* @deprecated since 1.8. Please use {@link #BeforeSaveEvent(Object, DBObject, String)}.
* @deprecated since 1.8. Please use {@link #BeforeSaveEvent(Object, Document, String)}.
*/
@Deprecated
public BeforeSaveEvent(E source, DBObject dbo) {
public BeforeSaveEvent(E source, Document dbo) {
super(source, dbo);
}
@@ -48,7 +48,7 @@ public class BeforeSaveEvent<E> extends MongoMappingEvent<E> {
* @param collectionName can be {@literal null}.
* @since 1.8
*/
public BeforeSaveEvent(E source, DBObject dbo, String collectionName) {
public BeforeSaveEvent(E source, Document dbo, String collectionName) {
super(source, dbo, collectionName);
}

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.mongodb.core.mapping.event;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
@@ -45,7 +46,7 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
*/
@Override
public void onBeforeSave(BeforeSaveEvent<Object> event) {
LOGGER.info("onBeforeSave: {}, {}", event.getSource(), event.getDBObject());
LOGGER.info("onBeforeSave: {}, {}", event.getSource(), event.getDocument());
}
/*
@@ -54,7 +55,7 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
*/
@Override
public void onAfterSave(AfterSaveEvent<Object> event) {
LOGGER.info("onAfterSave: {}, {}", event.getSource(), event.getDBObject());
LOGGER.info("onAfterSave: {}, {}", event.getSource(), event.getDocument());
}
/*
@@ -63,7 +64,7 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
*/
@Override
public void onAfterLoad(AfterLoadEvent<Object> event) {
LOGGER.info("onAfterLoad: {}", event.getDBObject());
LOGGER.info("onAfterLoad: {}", event.getDocument());
}
/*
@@ -72,7 +73,7 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
*/
@Override
public void onAfterConvert(AfterConvertEvent<Object> event) {
LOGGER.info("onAfterConvert: {}, {}", event.getDBObject(), event.getSource());
LOGGER.info("onAfterConvert: {}, {}", event.getDocument(), event.getSource());
}
/*
@@ -81,7 +82,7 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
*/
@Override
public void onAfterDelete(AfterDeleteEvent<Object> event) {
LOGGER.info("onAfterDelete: {}", event.getDBObject());
LOGGER.info("onAfterDelete: {}", event.getDocument());
}
/*
@@ -90,6 +91,6 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
*/
@Override
public void onBeforeDelete(BeforeDeleteEvent<Object> event) {
LOGGER.info("onBeforeDelete: {}", event.getDBObject());
LOGGER.info("onBeforeDelete: {}", event.getDocument());
}
}

View File

@@ -16,10 +16,9 @@
package org.springframework.data.mongodb.core.mapping.event;
import org.bson.Document;
import org.springframework.context.ApplicationEvent;
import com.mongodb.DBObject;
/**
* Base {@link ApplicationEvent} triggered by Spring Data MongoDB.
*
@@ -29,7 +28,7 @@ import com.mongodb.DBObject;
public class MongoMappingEvent<T> extends ApplicationEvent {
private static final long serialVersionUID = 1L;
private final DBObject dbo;
private final Document dbo;
private final String collectionName;
/**
@@ -37,10 +36,10 @@ public class MongoMappingEvent<T> extends ApplicationEvent {
*
* @param source must not be {@literal null}.
* @param dbo can be {@literal null}.
* @deprecated since 1.8. Please use {@link #MongoMappingEvent(Object, DBObject, String)}.
* @deprecated since 1.8. Please use {@link #MongoMappingEvent(Object, Document, String)}.
*/
@Deprecated
public MongoMappingEvent(T source, DBObject dbo) {
public MongoMappingEvent(T source, Document dbo) {
this(source, dbo, null);
}
@@ -51,7 +50,7 @@ public class MongoMappingEvent<T> extends ApplicationEvent {
* @param dbo can be {@literal null}.
* @param collectionName can be {@literal null}.
*/
public MongoMappingEvent(T source, DBObject dbo, String collectionName) {
public MongoMappingEvent(T source, Document dbo, String collectionName) {
super(source);
this.dbo = dbo;
@@ -61,7 +60,7 @@ public class MongoMappingEvent<T> extends ApplicationEvent {
/**
* @return {@literal null} if not set.
*/
public DBObject getDBObject() {
public Document getDocument() {
return dbo;
}

View File

@@ -20,6 +20,7 @@ import java.util.Set;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
@@ -52,18 +53,16 @@ public class ValidatingMongoEventListener extends AbstractMongoEventListener<Obj
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener#onBeforeSave(org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent)
*/
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void onBeforeSave(BeforeSaveEvent<Object> event) {
Object source = event.getSource();
LOG.debug("Validating object: {}", source);
Set violations = validator.validate(source);
LOG.debug("Validating object: {}", event.getSource());
Set violations = validator.validate(event.getSource());
if (!violations.isEmpty()) {
LOG.info("During object: {} validation violations found: {}", source, violations);
LOG.info("During object: {} validation violations found: {}", event.getSource(), violations);
throw new ConstraintViolationException(violations);
}
}

View File

@@ -15,8 +15,7 @@
*/
package org.springframework.data.mongodb.core.mapreduce;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* Collects the parameters required to perform a group operation on a collection. The query condition and the input
@@ -27,15 +26,15 @@ import com.mongodb.DBObject;
*/
public class GroupBy {
private DBObject dboKeys;
private Document dboKeys;
private String keyFunction;
private String initial;
private DBObject initialDbObject;
private Document initialDbObject;
private String reduce;
private String finalize;
public GroupBy(String... keys) {
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
for (String key : keys) {
dbo.put(key, 1);
}
@@ -45,7 +44,7 @@ public class GroupBy {
// NOTE GroupByCommand does not handle keyfunction.
public GroupBy(String key, boolean isKeyFunction) {
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
if (isKeyFunction) {
keyFunction = key;
} else {
@@ -67,7 +66,7 @@ public class GroupBy {
return this;
}
public GroupBy initialDocument(DBObject initialDocument) {
public GroupBy initialDocument(Document initialDocument) {
initialDbObject = initialDocument;
return this;
}
@@ -82,9 +81,9 @@ public class GroupBy {
return this;
}
public DBObject getGroupByObject() {
public Document getGroupByObject() {
// return new GroupCommand(dbCollection, dboKeys, condition, initial, reduce, finalize);
BasicDBObject dbo = new BasicDBObject();
Document dbo = new Document();
if (dboKeys != null) {
dbo.put("key", dboKeys);
}

View File

@@ -18,10 +18,9 @@ package org.springframework.data.mongodb.core.mapreduce;
import java.util.Iterator;
import java.util.List;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.DBObject;
/**
* Collects the results of executing a group operation.
*
@@ -32,13 +31,13 @@ import com.mongodb.DBObject;
public class GroupByResults<T> implements Iterable<T> {
private final List<T> mappedResults;
private final DBObject rawResults;
private final Document rawResults;
private double count;
private int keys;
private String serverUsed;
public GroupByResults(List<T> mappedResults, DBObject rawResults) {
public GroupByResults(List<T> mappedResults, Document rawResults) {
Assert.notNull(mappedResults);
Assert.notNull(rawResults);
@@ -65,7 +64,7 @@ public class GroupByResults<T> implements Iterable<T> {
return mappedResults.iterator();
}
public DBObject getRawResults() {
public Document getRawResults() {
return rawResults;
}

View File

@@ -18,8 +18,8 @@ package org.springframework.data.mongodb.core.mapreduce;
import java.util.HashMap;
import java.util.Map;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.bson.Document;
import com.mongodb.MapReduceCommand;
/**
@@ -260,8 +260,8 @@ public class MapReduceOptions {
return limit;
}
public DBObject getOptionsObject() {
BasicDBObject cmd = new BasicDBObject();
public Document getOptionsObject() {
Document cmd = new Document();
if (verbose != null) {
cmd.put("verbose", verbose);
@@ -288,8 +288,8 @@ public class MapReduceOptions {
return cmd;
}
protected BasicDBObject createOutObject() {
BasicDBObject out = new BasicDBObject();
protected Document createOutObject() {
Document out = new Document();
switch (outputType) {
case INLINE:

View File

@@ -18,9 +18,9 @@ package org.springframework.data.mongodb.core.mapreduce;
import java.util.Iterator;
import java.util.List;
import org.bson.Document;
import org.springframework.util.Assert;
import com.mongodb.DBObject;
import com.mongodb.MapReduceOutput;
/**
@@ -34,7 +34,7 @@ import com.mongodb.MapReduceOutput;
public class MapReduceResults<T> implements Iterable<T> {
private final List<T> mappedResults;
private final DBObject rawResults;
private final Document rawResults;
private final String outputCollection;
private final MapReduceTiming mapReduceTiming;
private final MapReduceCounts mapReduceCounts;
@@ -47,7 +47,7 @@ public class MapReduceResults<T> implements Iterable<T> {
* @deprecated since 1.7. Please use {@link #MapReduceResults(List, MapReduceOutput)}
*/
@Deprecated
public MapReduceResults(List<T> mappedResults, DBObject rawResults) {
public MapReduceResults(List<T> mappedResults, Document rawResults) {
Assert.notNull(mappedResults);
Assert.notNull(rawResults);
@@ -98,13 +98,13 @@ public class MapReduceResults<T> implements Iterable<T> {
return outputCollection;
}
public DBObject getRawResults() {
public Document getRawResults() {
return rawResults;
}
private static MapReduceTiming parseTiming(DBObject rawResults) {
private static MapReduceTiming parseTiming(Document rawResults) {
DBObject timing = (DBObject) rawResults.get("timing");
Document timing = (Document) rawResults.get("timing");
if (timing == null) {
return new MapReduceTiming(-1, -1, -1);
@@ -125,7 +125,7 @@ public class MapReduceResults<T> implements Iterable<T> {
* @param key
* @return
*/
private static Long getAsLong(DBObject source, String key) {
private static Long getAsLong(Document source, String key) {
Object raw = source.get(key);
@@ -133,14 +133,14 @@ public class MapReduceResults<T> implements Iterable<T> {
}
/**
* Parses the raw {@link DBObject} result into a {@link MapReduceCounts} value object.
* Parses the raw {@link Document} result into a {@link MapReduceCounts} value object.
*
* @param rawResults
* @return
*/
private static MapReduceCounts parseCounts(DBObject rawResults) {
private static MapReduceCounts parseCounts(Document rawResults) {
DBObject counts = (DBObject) rawResults.get("counts");
Document counts = (Document) rawResults.get("counts");
if (counts == null) {
return MapReduceCounts.NONE;
@@ -154,12 +154,12 @@ public class MapReduceResults<T> implements Iterable<T> {
}
/**
* Parses the output collection from the raw {@link DBObject} result.
* Parses the output collection from the raw {@link Document} result.
*
* @param rawResults
* @return
*/
private static String parseOutputCollection(DBObject rawResults) {
private static String parseOutputCollection(Document rawResults) {
Object resultField = rawResults.get("result");
@@ -167,8 +167,8 @@ public class MapReduceResults<T> implements Iterable<T> {
return null;
}
return resultField instanceof DBObject ? ((DBObject) resultField).get("collection").toString() : resultField
.toString();
return resultField instanceof Document ? ((Document) resultField).get("collection").toString()
: resultField.toString();
}
private static MapReduceCounts parseCounts(final MapReduceOutput mapReduceOutput) {

View File

@@ -17,7 +17,8 @@ package org.springframework.data.mongodb.core.query;
import static org.springframework.util.ObjectUtils.*;
import com.mongodb.BasicDBObject;
import org.bson.Document;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
@@ -32,24 +33,24 @@ import com.mongodb.util.JSON;
*/
public class BasicQuery extends Query {
private final DBObject queryObject;
private DBObject fieldsObject;
private DBObject sortObject;
private final Document queryObject;
private Document fieldsObject;
private Document sortObject;
public BasicQuery(String query) {
this((DBObject) JSON.parse(query));
this(query, null);
}
public BasicQuery(DBObject queryObject) {
public BasicQuery(Document queryObject) {
this(queryObject, null);
}
public BasicQuery(String query, String fields) {
this.queryObject = (DBObject) JSON.parse(query);
this.fieldsObject = (DBObject) JSON.parse(fields);
this.queryObject = query != null ? new Document(((DBObject) JSON.parse(query)).toMap()) : null;
this.fieldsObject = fields != null ? new Document(((DBObject) JSON.parse(fields)).toMap()) : null;
}
public BasicQuery(DBObject queryObject, DBObject fieldsObject) {
public BasicQuery(Document queryObject, Document fieldsObject) {
this.queryObject = queryObject;
this.fieldsObject = fieldsObject;
}
@@ -65,12 +66,12 @@ public class BasicQuery extends Query {
}
@Override
public DBObject getQueryObject() {
public Document getQueryObject() {
return this.queryObject;
}
@Override
public DBObject getFieldsObject() {
public Document getFieldsObject() {
if (fieldsObject == null) {
return super.getFieldsObject();
@@ -78,7 +79,7 @@ public class BasicQuery extends Query {
if (super.getFieldsObject() != null) {
DBObject combinedFieldsObject = new BasicDBObject();
Document combinedFieldsObject = new Document();
combinedFieldsObject.putAll(fieldsObject);
combinedFieldsObject.putAll(super.getFieldsObject());
return combinedFieldsObject;
@@ -88,14 +89,14 @@ public class BasicQuery extends Query {
}
@Override
public DBObject getSortObject() {
public Document getSortObject() {
BasicDBObject result = new BasicDBObject();
Document result = new Document();
if (sortObject != null) {
result.putAll(sortObject);
}
DBObject overrides = super.getSortObject();
Document overrides = super.getSortObject();
if (overrides != null) {
result.putAll(overrides);
}
@@ -103,7 +104,7 @@ public class BasicQuery extends Query {
return result;
}
public void setSortObject(DBObject sortObject) {
public void setSortObject(Document sortObject) {
this.sortObject = sortObject;
}
@@ -111,7 +112,7 @@ public class BasicQuery extends Query {
* @since 1.6
* @param fieldsObject
*/
protected void setFieldsObject(DBObject fieldsObject) {
protected void setFieldsObject(Document fieldsObject) {
this.fieldsObject = fieldsObject;
}

View File

@@ -18,20 +18,18 @@ package org.springframework.data.mongodb.core.query;
import java.util.Arrays;
import java.util.Collections;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
import org.bson.Document;
public class BasicUpdate extends Update {
private DBObject updateObject = null;
private Document updateObject = null;
public BasicUpdate(String updateString) {
super();
this.updateObject = (DBObject) JSON.parse(updateString);
this.updateObject = Document.parse(updateString);
}
public BasicUpdate(DBObject updateObject) {
public BasicUpdate(Document updateObject) {
super();
this.updateObject = updateObject;
}
@@ -62,7 +60,7 @@ public class BasicUpdate extends Update {
@Override
public Update pushAll(String key, Object[] values) {
DBObject keyValue = new BasicDBObject();
Document keyValue = new Document();
keyValue.put(key, values);
updateObject.put("$pushAll", keyValue);
return this;
@@ -88,7 +86,7 @@ public class BasicUpdate extends Update {
@Override
public Update pullAll(String key, Object[] values) {
DBObject keyValue = new BasicDBObject();
Document keyValue = new Document();
keyValue.put(key, Arrays.copyOf(values, values.length));
updateObject.put("$pullAll", keyValue);
return this;
@@ -101,7 +99,7 @@ public class BasicUpdate extends Update {
}
@Override
public DBObject getUpdateObject() {
public Document getUpdateObject() {
return updateObject;
}

View File

@@ -26,6 +26,8 @@ import java.util.Map.Entry;
import java.util.regex.Pattern;
import org.bson.BSON;
import org.bson.BsonRegularExpression;
import org.bson.Document;
import org.springframework.data.domain.Example;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Point;
@@ -39,8 +41,6 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Central class for creating queries. It follows a fluent API style so that you can easily chain together multiple
@@ -216,8 +216,8 @@ public class Criteria implements CriteriaDefinition {
*/
public Criteria in(Object... o) {
if (o.length > 1 && o[1] instanceof Collection) {
throw new InvalidMongoDbApiUsageException("You can only pass in one argument of type "
+ o[1].getClass().getName());
throw new InvalidMongoDbApiUsageException(
"You can only pass in one argument of type " + o[1].getClass().getName());
}
criteria.put("$in", Arrays.asList(o));
return this;
@@ -397,6 +397,16 @@ public class Criteria implements CriteriaDefinition {
return this;
}
public Criteria regex(BsonRegularExpression regex) {
if (lastOperatorWasNot()) {
return not(regex);
}
this.isValue = regex;
return this;
}
private Pattern toPattern(String regex, String options) {
Assert.notNull(regex);
return Pattern.compile(regex, options == null ? 0 : BSON.regexFlags(options));
@@ -582,8 +592,8 @@ public class Criteria implements CriteriaDefinition {
private Criteria registerCriteriaChainElement(Criteria criteria) {
if (lastOperatorWasNot()) {
throw new IllegalArgumentException("operator $not is not allowed around criteria chain element: "
+ criteria.getCriteriaObject());
throw new IllegalArgumentException(
"operator $not is not allowed around criteria chain element: " + criteria.getCriteriaObject());
} else {
criteriaChain.add(criteria);
}
@@ -598,16 +608,16 @@ public class Criteria implements CriteriaDefinition {
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.CriteriaDefinition#getCriteriaObject()
*/
public DBObject getCriteriaObject() {
public Document getCriteriaObject() {
if (this.criteriaChain.size() == 1) {
return criteriaChain.get(0).getSingleCriteriaObject();
} else if (CollectionUtils.isEmpty(this.criteriaChain) && !CollectionUtils.isEmpty(this.criteria)) {
return getSingleCriteriaObject();
} else {
DBObject criteriaObject = new BasicDBObject();
Document criteriaObject = new Document();
for (Criteria c : this.criteriaChain) {
DBObject dbo = c.getSingleCriteriaObject();
Document dbo = c.getSingleCriteriaObject();
for (String k : dbo.keySet()) {
setValue(criteriaObject, k, dbo.get(k));
}
@@ -616,9 +626,9 @@ public class Criteria implements CriteriaDefinition {
}
}
protected DBObject getSingleCriteriaObject() {
protected Document getSingleCriteriaObject() {
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
boolean not = false;
for (Entry<String, Object> entry : criteria.entrySet()) {
@@ -627,11 +637,11 @@ public class Criteria implements CriteriaDefinition {
Object value = entry.getValue();
if (requiresGeoJsonFormat(value)) {
value = new BasicDBObject("$geometry", value);
value = new Document("$geometry", value);
}
if (not) {
DBObject notDbo = new BasicDBObject();
Document notDbo = new Document();
notDbo.put(key, value);
dbo.put("$not", notDbo);
not = false;
@@ -646,12 +656,12 @@ public class Criteria implements CriteriaDefinition {
if (!StringUtils.hasText(this.key)) {
if (not) {
return new BasicDBObject("$not", dbo);
return new Document("$not", dbo);
}
return dbo;
}
DBObject queryCriteria = new BasicDBObject();
Document queryCriteria = new Document();
if (!NOT_SET.equals(isValue)) {
queryCriteria.put(this.key, this.isValue);
@@ -671,12 +681,12 @@ public class Criteria implements CriteriaDefinition {
return bsonList;
}
private void setValue(DBObject dbo, String key, Object value) {
private void setValue(Document dbo, String key, Object value) {
Object existing = dbo.get(key);
if (existing == null) {
dbo.put(key, value);
} else {
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, "
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDocument, "
+ "you can't add a second '" + key + "' expression specified as '" + key + " : " + value + "'. "
+ "Criteria already contains '" + key + " : " + existing + "'.");
}
@@ -690,15 +700,15 @@ public class Criteria implements CriteriaDefinition {
Object existingNearOperationValue = criteria.get(command);
if (existingNearOperationValue instanceof DBObject) {
if (existingNearOperationValue instanceof Document) {
((DBObject) existingNearOperationValue).put(operation, maxDistance);
((Document) existingNearOperationValue).put(operation, maxDistance);
return true;
} else if (existingNearOperationValue instanceof GeoJson) {
BasicDBObject dbo = new BasicDBObject("$geometry", existingNearOperationValue).append(operation, maxDistance);
Document dbo = new Document("$geometry", existingNearOperationValue).append(operation, maxDistance);
criteria.put(command, dbo);
return true;

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb.core.query;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* @author Oliver Gierke
@@ -24,11 +24,11 @@ import com.mongodb.DBObject;
public interface CriteriaDefinition {
/**
* Get {@link DBObject} representation.
* Get {@link Document} representation.
*
* @return
*/
DBObject getCriteriaObject();
Document getCriteriaObject();
/**
* Get the identifying {@literal key}.

View File

@@ -19,12 +19,10 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.bson.Document;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* @author Thomas Risberg
* @author Oliver Gierke
@@ -81,16 +79,16 @@ public class Field {
return this;
}
public DBObject getFieldsObject() {
public Document getFieldsObject() {
DBObject dbo = new BasicDBObject(criteria);
Document dbo = new Document((Map) criteria);
for (Entry<String, Object> entry : slices.entrySet()) {
dbo.put(entry.getKey(), new BasicDBObject("$slice", entry.getValue()));
dbo.put(entry.getKey(), new Document("$slice", entry.getValue()));
}
for (Entry<String, Criteria> entry : elemMatchs.entrySet()) {
DBObject dbObject = new BasicDBObject("$elemMatch", entry.getValue().getCriteriaObject());
Document dbObject = new Document("$elemMatch", entry.getValue().getCriteriaObject());
dbo.put(entry.getKey(), dbObject);
}

View File

@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.query;
import java.util.Arrays;
import org.bson.Document;
import org.springframework.data.domain.Pageable;
import org.springframework.data.geo.CustomMetric;
import org.springframework.data.geo.Distance;
@@ -25,9 +26,6 @@ import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Builder class to build near-queries.
*
@@ -407,13 +405,13 @@ public final class NearQuery {
}
/**
* Returns the {@link DBObject} built by the {@link NearQuery}.
* Returns the {@link Document} built by the {@link NearQuery}.
*
* @return
*/
public DBObject toDBObject() {
public Document toDocument() {
BasicDBObject dbObject = new BasicDBObject();
Document dbObject = new Document();
if (query != null) {
dbObject.put("query", query.getQueryObject());

View File

@@ -27,15 +27,13 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.bson.Document;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* @author Thomas Risberg
* @author Oliver Gierke
@@ -96,7 +94,7 @@ public class Query {
this.criteria.put(key, criteriaDefinition);
} else {
throw new InvalidMongoDbApiUsageException(
"Due to limitations of the com.mongodb.BasicDBObject, " + "you can't add a second '" + key + "' criteria. "
"Due to limitations of the com.mongodb.BasicDocument, " + "you can't add a second '" + key + "' criteria. "
+ "Query already contains '" + existing.getCriteriaObject() + "'.");
}
@@ -218,9 +216,9 @@ public class Query {
return this;
}
public DBObject getQueryObject() {
public Document getQueryObject() {
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
for (CriteriaDefinition definition : criteria.values()) {
dbo.putAll(definition.getCriteriaObject());
@@ -233,17 +231,17 @@ public class Query {
return dbo;
}
public DBObject getFieldsObject() {
public Document getFieldsObject() {
return this.fieldSpec == null ? null : fieldSpec.getFieldsObject();
}
public DBObject getSortObject() {
public Document getSortObject() {
if (this.sort == null) {
return null;
}
DBObject dbo = new BasicDBObject();
Document dbo = new Document();
for (org.springframework.data.domain.Sort.Order order : this.sort) {
dbo.put(order.getProperty(), order.isAscending() ? 1 : -1);

View File

@@ -22,10 +22,9 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.bson.Document;
import org.springframework.core.convert.converter.Converter;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
/**
@@ -41,7 +40,7 @@ public abstract class SerializationUtils {
}
/**
* Flattens out a given {@link DBObject}.
* Flattens out a given {@link Document}.
*
* <pre>
* <code>
@@ -63,7 +62,7 @@ public abstract class SerializationUtils {
* @return {@link Collections#emptyMap()} when source is {@literal null}
* @since 1.8
*/
public static Map<String, Object> flattenMap(DBObject source) {
public static Map<String, Object> flattenMap(Document source) {
if (source == null) {
return Collections.emptyMap();
@@ -76,9 +75,9 @@ public abstract class SerializationUtils {
private static void toFlatMap(String currentPath, Object source, Map<String, Object> map) {
if (source instanceof BasicDBObject) {
if (source instanceof Document) {
BasicDBObject dbo = (BasicDBObject) source;
Document dbo = (Document) source;
Iterator<Map.Entry<String, Object>> iter = dbo.entrySet().iterator();
String pathPrefix = currentPath.isEmpty() ? "" : currentPath + ".";
@@ -88,9 +87,9 @@ public abstract class SerializationUtils {
if (entry.getKey().startsWith("$")) {
if (map.containsKey(currentPath)) {
((BasicDBObject) map.get(currentPath)).put(entry.getKey(), entry.getValue());
((Document) map.get(currentPath)).put(entry.getKey(), entry.getValue());
} else {
map.put(currentPath, new BasicDBObject(entry.getKey(), entry.getValue()));
map.put(currentPath, new Document(entry.getKey(), entry.getValue()));
}
} else {
@@ -105,7 +104,7 @@ public abstract class SerializationUtils {
/**
* Serializes the given object into pseudo-JSON meaning it's trying to create a JSON representation as far as possible
* but falling back to the given object's {@link Object#toString()} method if it's not serializable. Useful for
* printing raw {@link DBObject}s containing complex values before actually converting them into Mongo native types.
* printing raw {@link Document}s containing complex values before actually converting them into Mongo native types.
*
* @param value
* @return
@@ -123,8 +122,8 @@ public abstract class SerializationUtils {
return toString((Collection<?>) value);
} else if (value instanceof Map) {
return toString((Map<?, ?>) value);
} else if (value instanceof DBObject) {
return toString(((DBObject) value).toMap());
} else if (value instanceof Document) {
return toString(((Document) value));
} else {
return String.format("{ $java : %s }", value.toString());
}

View File

@@ -18,13 +18,10 @@ package org.springframework.data.mongodb.core.query;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBObject;
/**
* Implementation of {@link CriteriaDefinition} to be used for full text search.
*
@@ -209,27 +206,27 @@ public class TextCriteria implements CriteriaDefinition {
* @see org.springframework.data.mongodb.core.query.CriteriaDefinition#getCriteriaObject()
*/
@Override
public DBObject getCriteriaObject() {
public Document getCriteriaObject() {
BasicDBObjectBuilder builder = new BasicDBObjectBuilder();
Document document = new Document();
if (StringUtils.hasText(language)) {
builder.add("$language", language);
document.put("$language", language);
}
if (!terms.isEmpty()) {
builder.add("$search", join(terms));
document.put("$search", join(terms));
}
if (caseSensitive != null) {
builder.add("$caseSensitive", caseSensitive);
document.put("$caseSensitive", caseSensitive);
}
if (diacriticSensitive != null) {
builder.add("$diacriticSensitive", diacriticSensitive);
document.put("$diacriticSensitive", diacriticSensitive);
}
return new BasicDBObject("$text", builder.get());
return new Document("$text", document);
}
private String join(Iterable<Term> terms) {

View File

@@ -17,8 +17,7 @@ package org.springframework.data.mongodb.core.query;
import java.util.Locale;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.bson.Document;
/**
* {@link Query} implementation to be used to for performing full text searches.
@@ -29,7 +28,7 @@ import com.mongodb.DBObject;
public class TextQuery extends Query {
private final String DEFAULT_SCORE_FIELD_FIELDNAME = "score";
private final DBObject META_TEXT_SCORE = new BasicDBObject("$meta", "textScore");
private final Document META_TEXT_SCORE = new Document("$meta", "textScore");
private String scoreFieldName = DEFAULT_SCORE_FIELD_FIELDNAME;
private boolean includeScore = false;
@@ -47,8 +46,8 @@ public class TextQuery extends Query {
/**
* Creates new {@link TextQuery} in {@code language}. <br />
* For a full list of supported languages see the mongdodb reference manual for <a
* href="http://docs.mongodb.org/manual/reference/text-search-languages/">Text Search Languages</a>.
* For a full list of supported languages see the mongdodb reference manual for
* <a href="http://docs.mongodb.org/manual/reference/text-search-languages/">Text Search Languages</a>.
*
* @param wordsAndPhrases
* @param language
@@ -61,8 +60,8 @@ public class TextQuery extends Query {
/**
* Creates new {@link TextQuery} using the {@code locale}s language.<br />
* For a full list of supported languages see the mongdodb reference manual for <a
* href="http://docs.mongodb.org/manual/reference/text-search-languages/">Text Search Languages</a>.
* For a full list of supported languages see the mongdodb reference manual for
* <a href="http://docs.mongodb.org/manual/reference/text-search-languages/">Text Search Languages</a>.
*
* @param wordsAndPhrases
* @param locale
@@ -150,16 +149,16 @@ public class TextQuery extends Query {
* @see org.springframework.data.mongodb.core.query.Query#getFieldsObject()
*/
@Override
public DBObject getFieldsObject() {
public Document getFieldsObject() {
if (!this.includeScore) {
return super.getFieldsObject();
}
DBObject fields = super.getFieldsObject();
Document fields = super.getFieldsObject();
if (fields == null) {
fields = new BasicDBObject();
fields = new Document();
}
fields.put(getScoreFieldName(), META_TEXT_SCORE);
@@ -171,9 +170,9 @@ public class TextQuery extends Query {
* @see org.springframework.data.mongodb.core.query.Query#getSortObject()
*/
@Override
public DBObject getSortObject() {
public Document getSortObject() {
DBObject sort = new BasicDBObject();
Document sort = new Document();
if (this.sortByScore) {
sort.put(getScoreFieldName(), META_TEXT_SCORE);

View File

@@ -26,13 +26,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bson.Document;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* Class to easily construct MongoDB update clauses.
*
@@ -66,17 +64,17 @@ public class Update {
}
/**
* Creates an {@link Update} instance from the given {@link DBObject}. Allows to explicitly exclude fields from making
* Creates an {@link Update} instance from the given {@link Document}. Allows to explicitly exclude fields from making
* it into the created {@link Update} object. Note, that this will set attributes directly and <em>not</em> use
* {@literal $set}. This means fields not given in the {@link DBObject} will be nulled when executing the update. To
* create an only-updating {@link Update} instance of a {@link DBObject}, call {@link #set(String, Object)} for each
* {@literal $set}. This means fields not given in the {@link Document} will be nulled when executing the update. To
* create an only-updating {@link Update} instance of a {@link Document}, call {@link #set(String, Object)} for each
* value in it.
*
* @param object the source {@link DBObject} to create the update from.
* @param object the source {@link Document} to create the update from.
* @param exclude the fields to exclude.
* @return
*/
public static Update fromDBObject(DBObject object, String... exclude) {
public static Update fromDocument(Document object, String... exclude) {
Update update = new Update();
List<String> excludeList = Arrays.asList(exclude);
@@ -89,8 +87,8 @@ public class Update {
Object value = object.get(key);
update.modifierOps.put(key, value);
if (isKeyword(key) && value instanceof DBObject) {
update.keysToUpdate.addAll(((DBObject) value).keySet());
if (isKeyword(key) && value instanceof Document) {
update.keysToUpdate.addAll(((Document) value).keySet());
} else {
update.keysToUpdate.add(key);
}
@@ -192,7 +190,7 @@ public class Update {
* @return
*/
public Update pushAll(String key, Object[] values) {
addMultiFieldOperation("$pushAll", key, Arrays.copyOf(values, values.length));
addMultiFieldOperation("$pushAll", key, Arrays.asList(values));
return this;
}
@@ -256,7 +254,7 @@ public class Update {
* @return
*/
public Update pullAll(String key, Object[] values) {
addMultiFieldOperation("$pullAll", key, Arrays.copyOf(values, values.length));
addMultiFieldOperation("$pullAll", key, Arrays.asList(values));
return this;
}
@@ -297,7 +295,7 @@ public class Update {
*/
public Update currentTimestamp(String key) {
addMultiFieldOperation("$currentDate", key, new BasicDBObject("$type", "timestamp"));
addMultiFieldOperation("$currentDate", key, new Document("$type", "timestamp"));
return this;
}
@@ -362,8 +360,8 @@ public class Update {
return new BitwiseOperatorBuilder(this, key);
}
public DBObject getUpdateObject() {
return new BasicDBObject(modifierOps);
public Document getUpdateObject() {
return new Document(modifierOps);
}
/**
@@ -379,7 +377,7 @@ public class Update {
Assert.hasText(key, "Key/Path for update must not be null or blank.");
modifierOps.put(operator, new BasicDBObject(key, value));
modifierOps.put(operator, new Document(key, value));
this.keysToUpdate.add(key);
}
@@ -387,14 +385,14 @@ public class Update {
Assert.hasText(key, "Key/Path for update must not be null or blank.");
Object existingValue = this.modifierOps.get(operator);
DBObject keyValueMap;
Document keyValueMap;
if (existingValue == null) {
keyValueMap = new BasicDBObject();
keyValueMap = new Document();
this.modifierOps.put(operator, keyValueMap);
} else {
if (existingValue instanceof BasicDBObject) {
keyValueMap = (BasicDBObject) existingValue;
if (existingValue instanceof Document) {
keyValueMap = (Document) existingValue;
} else {
throw new InvalidDataAccessApiUsageException(
"Modifier Operations should be a LinkedHashMap but was " + existingValue.getClass());
@@ -904,7 +902,7 @@ public class Update {
}
private void addFieldOperation(BitwiseOperator operator, Number value) {
reference.addMultiFieldOperation(BIT_OPERATOR, key, new BasicDBObject(operator.toString(), value));
reference.addMultiFieldOperation(BIT_OPERATOR, key, new Document(operator.toString(), value));
}
}
}

Some files were not shown because too many files have changed in this diff Show More