Change indentation from spaces to tabs.
This commit is contained in:
@@ -19,39 +19,39 @@ import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
public class CannotGetMongoDbConnectionException extends DataAccessResourceFailureException {
|
||||
|
||||
private String username;
|
||||
|
||||
private char[] password;
|
||||
|
||||
private String database;
|
||||
|
||||
private static final long serialVersionUID = 1172099106475265589L;
|
||||
private String username;
|
||||
|
||||
public CannotGetMongoDbConnectionException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public CannotGetMongoDbConnectionException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
private char[] password;
|
||||
|
||||
public CannotGetMongoDbConnectionException(String msg, String database, String username, char[] password2) {
|
||||
super(msg);
|
||||
this.username = username;
|
||||
this.password = password2;
|
||||
this.database = database;
|
||||
}
|
||||
private String database;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
private static final long serialVersionUID = 1172099106475265589L;
|
||||
|
||||
public char[] getPassword() {
|
||||
return password;
|
||||
}
|
||||
public CannotGetMongoDbConnectionException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public CannotGetMongoDbConnectionException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CannotGetMongoDbConnectionException(String msg, String database, String username, char[] password2) {
|
||||
super(msg);
|
||||
this.username = username;
|
||||
this.password = password2;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public char[] getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,6 @@ import org.springframework.dao.DataAccessException;
|
||||
|
||||
public interface CollectionCallback<T> {
|
||||
|
||||
T doInCollection(DBCollection collection) throws MongoException, DataAccessException;
|
||||
T doInCollection(DBCollection collection) throws MongoException, DataAccessException;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,55 +17,57 @@ package org.springframework.data.document.mongodb;
|
||||
|
||||
/**
|
||||
* Provides a simple wrapper to encapsulate the variety of settings you can use when creating a collection.
|
||||
*
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
public class CollectionOptions {
|
||||
|
||||
private Integer maxDocuments;
|
||||
private Integer maxDocuments;
|
||||
|
||||
private Integer size;
|
||||
private Integer size;
|
||||
|
||||
private Boolean capped;
|
||||
private Boolean capped;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>CollectionOptions</code> instance.
|
||||
*
|
||||
* @param size the collection size in bytes, this data space is preallocated
|
||||
* @param maxDocuments the maximum number of documents in the collection.
|
||||
* @param capped true to created a "capped" collection (fixed size with auto-FIFO behavior
|
||||
* based on insertion order), false otherwise.
|
||||
*/
|
||||
public CollectionOptions(Integer size, Integer maxDocuments, Boolean capped) {
|
||||
super();
|
||||
this.maxDocuments = maxDocuments;
|
||||
this.size = size;
|
||||
this.capped = capped;
|
||||
}
|
||||
/**
|
||||
* Constructs a new <code>CollectionOptions</code> instance.
|
||||
*
|
||||
* @param size
|
||||
* the collection size in bytes, this data space is preallocated
|
||||
* @param maxDocuments
|
||||
* the maximum number of documents in the collection.
|
||||
* @param capped
|
||||
* true to created a "capped" collection (fixed size with auto-FIFO behavior based on insertion order), false
|
||||
* otherwise.
|
||||
*/
|
||||
public CollectionOptions(Integer size, Integer maxDocuments, Boolean capped) {
|
||||
super();
|
||||
this.maxDocuments = maxDocuments;
|
||||
this.size = size;
|
||||
this.capped = capped;
|
||||
}
|
||||
|
||||
public Integer getMaxDocuments() {
|
||||
return maxDocuments;
|
||||
}
|
||||
public Integer getMaxDocuments() {
|
||||
return maxDocuments;
|
||||
}
|
||||
|
||||
public void setMaxDocuments(Integer maxDocuments) {
|
||||
this.maxDocuments = maxDocuments;
|
||||
}
|
||||
public void setMaxDocuments(Integer maxDocuments) {
|
||||
this.maxDocuments = maxDocuments;
|
||||
}
|
||||
|
||||
public Integer getSize() {
|
||||
return size;
|
||||
}
|
||||
public Integer getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Integer size) {
|
||||
this.size = size;
|
||||
}
|
||||
public void setSize(Integer size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public Boolean getCapped() {
|
||||
return capped;
|
||||
}
|
||||
|
||||
public void setCapped(Boolean capped) {
|
||||
this.capped = capped;
|
||||
}
|
||||
public Boolean getCapped() {
|
||||
return capped;
|
||||
}
|
||||
|
||||
public void setCapped(Boolean capped) {
|
||||
this.capped = capped;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,18 +17,17 @@ package org.springframework.data.document.mongodb;
|
||||
|
||||
import com.mongodb.DBCursor;
|
||||
|
||||
|
||||
/**
|
||||
* Simple callback interface to allow customization of a {@link DBCursor}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface CursorPreparer {
|
||||
|
||||
/**
|
||||
* Prepare the given cursor (apply limits, skips and so on). Returns th eprepared cursor.
|
||||
*
|
||||
* @param cursor
|
||||
*/
|
||||
DBCursor prepare(DBCursor cursor);
|
||||
/**
|
||||
* Prepare the given cursor (apply limits, skips and so on). Returns th eprepared cursor.
|
||||
*
|
||||
* @param cursor
|
||||
*/
|
||||
DBCursor prepare(DBCursor cursor);
|
||||
}
|
||||
|
||||
@@ -21,5 +21,5 @@ import org.springframework.dao.DataAccessException;
|
||||
|
||||
public interface DbCallback<T> {
|
||||
|
||||
T doInDB(DB db) throws MongoException, DataAccessException;
|
||||
T doInDB(DB db) throws MongoException, DataAccessException;
|
||||
}
|
||||
|
||||
@@ -8,63 +8,59 @@ import org.springframework.transaction.support.ResourceHolderSupport;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
class DbHolder extends ResourceHolderSupport {
|
||||
private static final Object DEFAULT_KEY = new Object();
|
||||
private static final Object DEFAULT_KEY = new Object();
|
||||
|
||||
private final Map<Object, DB> dbMap = new ConcurrentHashMap<Object, DB>();
|
||||
private final Map<Object, DB> dbMap = new ConcurrentHashMap<Object, DB>();
|
||||
|
||||
public DbHolder(DB db) {
|
||||
addDB(db);
|
||||
}
|
||||
|
||||
public DbHolder(DB db) {
|
||||
addDB(db);
|
||||
}
|
||||
public DbHolder(Object key, DB db) {
|
||||
addDB(key, db);
|
||||
}
|
||||
|
||||
public DbHolder(Object key, DB db) {
|
||||
addDB(key, db);
|
||||
}
|
||||
public DB getDB() {
|
||||
return getDB(DEFAULT_KEY);
|
||||
}
|
||||
|
||||
public DB getDB(Object key) {
|
||||
return this.dbMap.get(key);
|
||||
}
|
||||
|
||||
public DB getDB() {
|
||||
return getDB(DEFAULT_KEY);
|
||||
}
|
||||
public DB getAnyDB() {
|
||||
if (!this.dbMap.isEmpty()) {
|
||||
return this.dbMap.values().iterator().next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public DB getDB(Object key) {
|
||||
return this.dbMap.get(key);
|
||||
}
|
||||
public void addDB(DB session) {
|
||||
addDB(DEFAULT_KEY, session);
|
||||
}
|
||||
|
||||
public void addDB(Object key, DB session) {
|
||||
Assert.notNull(key, "Key must not be null");
|
||||
Assert.notNull(session, "DB must not be null");
|
||||
this.dbMap.put(key, session);
|
||||
}
|
||||
|
||||
public DB getAnyDB() {
|
||||
if (!this.dbMap.isEmpty()) {
|
||||
return this.dbMap.values().iterator().next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public DB removeDB(Object key) {
|
||||
return this.dbMap.remove(key);
|
||||
}
|
||||
|
||||
public void addDB(DB session) {
|
||||
addDB(DEFAULT_KEY, session);
|
||||
}
|
||||
public boolean containsDB(DB session) {
|
||||
return this.dbMap.containsValue(session);
|
||||
}
|
||||
|
||||
public void addDB(Object key, DB session) {
|
||||
Assert.notNull(key, "Key must not be null");
|
||||
Assert.notNull(session, "DB must not be null");
|
||||
this.dbMap.put(key, session);
|
||||
}
|
||||
public boolean isEmpty() {
|
||||
return this.dbMap.isEmpty();
|
||||
}
|
||||
|
||||
public DB removeDB(Object key) {
|
||||
return this.dbMap.remove(key);
|
||||
}
|
||||
|
||||
public boolean containsDB(DB session) {
|
||||
return this.dbMap.containsValue(session);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.dbMap.isEmpty();
|
||||
}
|
||||
|
||||
public boolean doesNotHoldNonDefaultDB() {
|
||||
synchronized (this.dbMap) {
|
||||
return this.dbMap.isEmpty() ||
|
||||
(this.dbMap.size() == 1 && this.dbMap.containsKey(DEFAULT_KEY));
|
||||
}
|
||||
}
|
||||
public boolean doesNotHoldNonDefaultDB() {
|
||||
synchronized (this.dbMap) {
|
||||
return this.dbMap.isEmpty() || (this.dbMap.size() == 1 && this.dbMap.containsKey(DEFAULT_KEY));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,71 +24,72 @@ import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
|
||||
/**
|
||||
* Mongo server administration exposed via JMX annotations
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
|
||||
@ManagedResource(description = "Mongo Admin Operations")
|
||||
public class MongoAdmin implements MongoAdminOperations {
|
||||
|
||||
/**
|
||||
* Logger available to subclasses
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
/**
|
||||
* Logger available to subclasses
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private Mongo mongo;
|
||||
private String username;
|
||||
private String password;
|
||||
private Mongo mongo;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public MongoAdmin(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
public MongoAdmin(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoAdminOperations#dropDatabase(java.lang.String)
|
||||
*/
|
||||
@ManagedOperation
|
||||
public void dropDatabase(String databaseName) {
|
||||
getDB(databaseName).dropDatabase();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoAdminOperations#dropDatabase(java.lang.String)
|
||||
*/
|
||||
@ManagedOperation
|
||||
public void dropDatabase(String databaseName) {
|
||||
getDB(databaseName).dropDatabase();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoAdminOperations#createDatabase(java.lang.String)
|
||||
*/
|
||||
@ManagedOperation
|
||||
public void createDatabase(String databaseName) {
|
||||
getDB(databaseName);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoAdminOperations#createDatabase(java.lang.String)
|
||||
*/
|
||||
@ManagedOperation
|
||||
public void createDatabase(String databaseName) {
|
||||
getDB(databaseName);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoAdminOperations#getDatabaseStats(java.lang.String)
|
||||
*/
|
||||
@ManagedOperation
|
||||
public String getDatabaseStats(String databaseName) {
|
||||
return getDB(databaseName).getStats().toString();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoAdminOperations#getDatabaseStats(java.lang.String)
|
||||
*/
|
||||
@ManagedOperation
|
||||
public String getDatabaseStats(String databaseName) {
|
||||
return getDB(databaseName).getStats().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the username to use to connect to the Mongo database
|
||||
*
|
||||
* @param username The username to use
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
/**
|
||||
* Sets the username to use to connect to the Mongo database
|
||||
*
|
||||
* @param username
|
||||
* The username to use
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password to use to authenticate with the Mongo database.
|
||||
*
|
||||
* @param password The password to use
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
/**
|
||||
* Sets the password to use to authenticate with the Mongo database.
|
||||
*
|
||||
* @param password
|
||||
* The password to use
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
|
||||
this.password = password;
|
||||
}
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
|
||||
DB getDB(String databaseName) {
|
||||
return MongoDbUtils.getDB(mongo, databaseName, username, password == null ? null : password.toCharArray());
|
||||
}
|
||||
DB getDB(String databaseName) {
|
||||
return MongoDbUtils.getDB(mongo, databaseName, username, password == null ? null : password.toCharArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
|
||||
public interface MongoAdminOperations {
|
||||
|
||||
@ManagedOperation
|
||||
public abstract void dropDatabase(String databaseName);
|
||||
@ManagedOperation
|
||||
public abstract void dropDatabase(String databaseName);
|
||||
|
||||
@ManagedOperation
|
||||
public abstract void createDatabase(String databaseName);
|
||||
@ManagedOperation
|
||||
public abstract void createDatabase(String databaseName);
|
||||
|
||||
@ManagedOperation
|
||||
public abstract String getDatabaseStats(String databaseName);
|
||||
@ManagedOperation
|
||||
public abstract String getDatabaseStats(String databaseName);
|
||||
|
||||
}
|
||||
@@ -27,8 +27,9 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* Helper class featuring helper methods for internal MongoDb classes.
|
||||
* <p/>
|
||||
* <p>Mainly intended for internal use within the framework.
|
||||
*
|
||||
* <p>
|
||||
* Mainly intended for internal use within the framework.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Graeme Rocher
|
||||
* @author Oliver Gierke
|
||||
@@ -36,133 +37,138 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public abstract class MongoDbUtils {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(MongoDbUtils.class);
|
||||
private static final Log LOGGER = LogFactory.getLog(MongoDbUtils.class);
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private MongoDbUtils() {
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private MongoDbUtils() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
|
||||
*
|
||||
* @param mongo The {@link Mongo} instance
|
||||
* @param databaseName The database name
|
||||
* @return The {@link DB} connection
|
||||
*/
|
||||
public static DB getDB(Mongo mongo, String databaseName) {
|
||||
return doGetDB(mongo, databaseName, null, null, true);
|
||||
}
|
||||
/**
|
||||
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
|
||||
*
|
||||
* @param mongo
|
||||
* The {@link Mongo} instance
|
||||
* @param databaseName
|
||||
* The database name
|
||||
* @return The {@link DB} connection
|
||||
*/
|
||||
public static DB getDB(Mongo mongo, String databaseName) {
|
||||
return doGetDB(mongo, databaseName, null, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
|
||||
*
|
||||
* @param mongo The {@link Mongo} instance
|
||||
* @param databaseName The database name
|
||||
* @param username The username to authenticate with
|
||||
* @param password The password to authenticate with
|
||||
* @return The {@link DB} connection
|
||||
*/
|
||||
public static DB getDB(Mongo mongo, String databaseName, String username, char[] password) {
|
||||
return doGetDB(mongo, databaseName, username, password, true);
|
||||
}
|
||||
/**
|
||||
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
|
||||
*
|
||||
* @param mongo
|
||||
* The {@link Mongo} instance
|
||||
* @param databaseName
|
||||
* The database name
|
||||
* @param username
|
||||
* The username to authenticate with
|
||||
* @param password
|
||||
* The password to authenticate with
|
||||
* @return The {@link DB} connection
|
||||
*/
|
||||
public static DB getDB(Mongo mongo, String databaseName, String username, char[] password) {
|
||||
return doGetDB(mongo, databaseName, username, password, true);
|
||||
}
|
||||
|
||||
public static DB doGetDB(Mongo mongo, String databaseName, String username, char[] password, boolean allowCreate) {
|
||||
Assert.notNull(mongo, "No Mongo instance specified");
|
||||
public static DB doGetDB(Mongo mongo, String databaseName, String username, char[] password, boolean allowCreate) {
|
||||
Assert.notNull(mongo, "No Mongo instance specified");
|
||||
|
||||
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
||||
if (dbHolder != null && !dbHolder.isEmpty()) {
|
||||
// pre-bound Mongo DB
|
||||
DB db = null;
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive() &&
|
||||
dbHolder.doesNotHoldNonDefaultDB()) {
|
||||
// Spring transaction management is active ->
|
||||
db = dbHolder.getDB();
|
||||
if (db != null && !dbHolder.isSynchronizedWithTransaction()) {
|
||||
LOGGER.debug("Registering Spring transaction synchronization for existing Mongo DB");
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(dbHolder, mongo));
|
||||
dbHolder.setSynchronizedWithTransaction(true);
|
||||
}
|
||||
}
|
||||
if (db != null) {
|
||||
return db;
|
||||
}
|
||||
}
|
||||
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
||||
if (dbHolder != null && !dbHolder.isEmpty()) {
|
||||
// pre-bound Mongo DB
|
||||
DB db = null;
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive() && dbHolder.doesNotHoldNonDefaultDB()) {
|
||||
// Spring transaction management is active ->
|
||||
db = dbHolder.getDB();
|
||||
if (db != null && !dbHolder.isSynchronizedWithTransaction()) {
|
||||
LOGGER.debug("Registering Spring transaction synchronization for existing Mongo DB");
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(dbHolder, mongo));
|
||||
dbHolder.setSynchronizedWithTransaction(true);
|
||||
}
|
||||
}
|
||||
if (db != null) {
|
||||
return db;
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.trace("Getting Mongo Database name=["+databaseName+"]");
|
||||
DB db = mongo.getDB(databaseName);
|
||||
|
||||
boolean credentialsGiven = username != null && password != null;
|
||||
if (credentialsGiven && !db.isAuthenticated()) {
|
||||
//Note, can only authenticate once against the same com.mongodb.DB object.
|
||||
if (!db.authenticate(username, password)) {
|
||||
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName +
|
||||
"], username = [" + username + "], password = [" + new String(password) + "]", databaseName, username, password );
|
||||
}
|
||||
}
|
||||
LOGGER.trace("Getting Mongo Database name=[" + databaseName + "]");
|
||||
DB db = mongo.getDB(databaseName);
|
||||
|
||||
// Use same Session for further Mongo actions within the transaction.
|
||||
// Thread object will get removed by synchronization at transaction completion.
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
// We're within a Spring-managed transaction, possibly from JtaTransactionManager.
|
||||
LOGGER.debug("Registering Spring transaction synchronization for new Hibernate Session");
|
||||
DbHolder holderToUse = dbHolder;
|
||||
if (holderToUse == null) {
|
||||
holderToUse = new DbHolder(db);
|
||||
} else {
|
||||
holderToUse.addDB(db);
|
||||
}
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(holderToUse, mongo));
|
||||
holderToUse.setSynchronizedWithTransaction(true);
|
||||
if (holderToUse != dbHolder) {
|
||||
TransactionSynchronizationManager.bindResource(mongo, holderToUse);
|
||||
}
|
||||
}
|
||||
boolean credentialsGiven = username != null && password != null;
|
||||
if (credentialsGiven && !db.isAuthenticated()) {
|
||||
// Note, can only authenticate once against the same com.mongodb.DB object.
|
||||
if (!db.authenticate(username, password)) {
|
||||
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName
|
||||
+ "], username = [" + username + "], password = [" + new String(password) + "]", databaseName, username,
|
||||
password);
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether we are allowed to return the DB.
|
||||
if (!allowCreate && !isDBTransactional(db, mongo)) {
|
||||
throw new IllegalStateException("No Mongo DB bound to thread, " +
|
||||
"and configuration does not allow creation of non-transactional one here");
|
||||
}
|
||||
// Use same Session for further Mongo actions within the transaction.
|
||||
// Thread object will get removed by synchronization at transaction completion.
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
// We're within a Spring-managed transaction, possibly from JtaTransactionManager.
|
||||
LOGGER.debug("Registering Spring transaction synchronization for new Hibernate Session");
|
||||
DbHolder holderToUse = dbHolder;
|
||||
if (holderToUse == null) {
|
||||
holderToUse = new DbHolder(db);
|
||||
} else {
|
||||
holderToUse.addDB(db);
|
||||
}
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(holderToUse, mongo));
|
||||
holderToUse.setSynchronizedWithTransaction(true);
|
||||
if (holderToUse != dbHolder) {
|
||||
TransactionSynchronizationManager.bindResource(mongo, holderToUse);
|
||||
}
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
// Check whether we are allowed to return the DB.
|
||||
if (!allowCreate && !isDBTransactional(db, mongo)) {
|
||||
throw new IllegalStateException("No Mongo DB bound to thread, "
|
||||
+ "and configuration does not allow creation of non-transactional one here");
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given DB instance is transactional, that is,
|
||||
* bound to the current thread by Spring's transaction facilities.
|
||||
*
|
||||
* @param db the DB to check
|
||||
* @param mongo the Mongo instance that the DB was created with
|
||||
* (may be <code>null</code>)
|
||||
* @return whether the DB is transactional
|
||||
*/
|
||||
public static boolean isDBTransactional(DB db, Mongo mongo) {
|
||||
if (mongo == null) {
|
||||
return false;
|
||||
}
|
||||
DbHolder dbHolder =
|
||||
(DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
||||
return (dbHolder != null && dbHolder.containsDB(db));
|
||||
}
|
||||
/**
|
||||
* Return whether the given DB instance is transactional, that is, bound to the current thread by Spring's transaction
|
||||
* facilities.
|
||||
*
|
||||
* @param db
|
||||
* the DB to check
|
||||
* @param mongo
|
||||
* the Mongo instance that the DB was created with (may be <code>null</code>)
|
||||
* @return whether the DB is transactional
|
||||
*/
|
||||
public static boolean isDBTransactional(DB db, Mongo mongo) {
|
||||
if (mongo == null) {
|
||||
return false;
|
||||
}
|
||||
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
||||
return (dbHolder != null && dbHolder.containsDB(db));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform actual closing of the Mongo DB object,
|
||||
* catching and logging any cleanup exceptions thrown.
|
||||
*
|
||||
* @param db the DB to close (may be <code>null</code>)
|
||||
*/
|
||||
public static void closeDB(DB db) {
|
||||
if (db != null) {
|
||||
LOGGER.debug("Closing Mongo DB object");
|
||||
try {
|
||||
db.requestDone();
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.debug("Unexpected exception on closing Mongo DB object", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Perform actual closing of the Mongo DB object, catching and logging any cleanup exceptions thrown.
|
||||
*
|
||||
* @param db
|
||||
* the DB to close (may be <code>null</code>)
|
||||
*/
|
||||
public static void closeDB(DB db) {
|
||||
if (db != null) {
|
||||
LOGGER.debug("Closing Mongo DB object");
|
||||
try {
|
||||
db.requestDone();
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.debug("Unexpected exception on closing Mongo DB object", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,51 +34,52 @@ import org.springframework.data.document.UncategorizedDocumentStoreException;
|
||||
* Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate
|
||||
* exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is
|
||||
* appropriate: any other exception may have resulted from user code, and should not be translated.
|
||||
*
|
||||
* @param ex runtime exception that occurred
|
||||
*
|
||||
* @param ex
|
||||
* runtime exception that occurred
|
||||
* @author Oliver Gierke
|
||||
* @return the corresponding DataAccessException instance, or {@literal null} if the exception should not be translated
|
||||
*/
|
||||
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator#
|
||||
* translateExceptionIfPossible(java.lang.RuntimeException)
|
||||
*/
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator#
|
||||
* translateExceptionIfPossible(java.lang.RuntimeException)
|
||||
*/
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
|
||||
// Check for well-known MongoException subclasses.
|
||||
// Check for well-known MongoException subclasses.
|
||||
|
||||
// All other MongoExceptions
|
||||
if (ex instanceof DuplicateKey) {
|
||||
return new DuplicateKeyException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof Network) {
|
||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof CursorNotFound) {
|
||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof MongoException) {
|
||||
int code = ((MongoException)ex).getCode();
|
||||
if (code == 11000 || code == 11001) {
|
||||
throw new DuplicateKeyException(ex.getMessage(), ex);
|
||||
} else if (code == 12000 || code == 13440) {
|
||||
throw new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
} else if (code == 10003 || code == 12001 || code == 12010 || code == 12011 || code == 12012 ) {
|
||||
throw new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
return new UncategorizedDocumentStoreException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof MongoInternalException) {
|
||||
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
// All other MongoExceptions
|
||||
if (ex instanceof DuplicateKey) {
|
||||
return new DuplicateKeyException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof Network) {
|
||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof CursorNotFound) {
|
||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof MongoException) {
|
||||
int code = ((MongoException) ex).getCode();
|
||||
if (code == 11000 || code == 11001) {
|
||||
throw new DuplicateKeyException(ex.getMessage(), ex);
|
||||
} else if (code == 12000 || code == 13440) {
|
||||
throw new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
} else if (code == 10003 || code == 12001 || code == 12010 || code == 12011 || code == 12012) {
|
||||
throw new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
return new UncategorizedDocumentStoreException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof MongoInternalException) {
|
||||
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
// If we get here, we have an exception that resulted from user code,
|
||||
// rather than the persistence provider, so we return null to indicate
|
||||
// that translation should not occur.
|
||||
return null;
|
||||
}
|
||||
// If we get here, we have an exception that resulted from user code,
|
||||
// rather than the persistence provider, so we return null to indicate
|
||||
// that translation should not occur.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,101 +31,100 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Convenient factory for configuring MongoDB.
|
||||
*
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Graeme Rocher
|
||||
* @since 1.0
|
||||
*/
|
||||
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, PersistenceExceptionTranslator {
|
||||
|
||||
/**
|
||||
* Logger, available to subclasses.
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
* Logger, available to subclasses.
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
private Mongo mongo;
|
||||
private MongoOptions mongoOptions;
|
||||
private String host;
|
||||
private Integer port;
|
||||
private List<ServerAddress> replicaSetSeeds;
|
||||
private List<ServerAddress> replicaPair;
|
||||
|
||||
private Mongo mongo;
|
||||
private MongoOptions mongoOptions;
|
||||
private String host;
|
||||
private Integer port;
|
||||
private List<ServerAddress> replicaSetSeeds;
|
||||
private List<ServerAddress> replicaPair;
|
||||
private PersistenceExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
|
||||
|
||||
private PersistenceExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
|
||||
public void setMongoOptions(MongoOptions mongoOptions) {
|
||||
this.mongoOptions = mongoOptions;
|
||||
}
|
||||
|
||||
public void setMongoOptions(MongoOptions mongoOptions) {
|
||||
this.mongoOptions = mongoOptions;
|
||||
}
|
||||
public void setReplicaSetSeeds(List<ServerAddress> replicaSetSeeds) {
|
||||
this.replicaSetSeeds = replicaSetSeeds;
|
||||
}
|
||||
|
||||
public void setReplicaSetSeeds(List<ServerAddress> replicaSetSeeds) {
|
||||
this.replicaSetSeeds = replicaSetSeeds;
|
||||
}
|
||||
public void setReplicaPair(List<ServerAddress> replicaPair) {
|
||||
this.replicaPair = replicaPair;
|
||||
}
|
||||
|
||||
public void setReplicaPair(List<ServerAddress> replicaPair) {
|
||||
this.replicaPair = replicaPair;
|
||||
}
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
public PersistenceExceptionTranslator getExceptionTranslator() {
|
||||
return exceptionTranslator;
|
||||
}
|
||||
|
||||
public PersistenceExceptionTranslator getExceptionTranslator() {
|
||||
return exceptionTranslator;
|
||||
}
|
||||
public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) {
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
}
|
||||
|
||||
public void setExceptionTranslator(
|
||||
PersistenceExceptionTranslator exceptionTranslator) {
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
}
|
||||
public Mongo getObject() throws Exception {
|
||||
Assert.notNull(mongo, "Mongo must not be null");
|
||||
return mongo;
|
||||
}
|
||||
|
||||
public Mongo getObject() throws Exception {
|
||||
Assert.notNull(mongo, "Mongo must not be null");
|
||||
return mongo;
|
||||
}
|
||||
public Class<? extends Mongo> getObjectType() {
|
||||
return Mongo.class;
|
||||
}
|
||||
|
||||
public Class<? extends Mongo> getObjectType() {
|
||||
return Mongo.class;
|
||||
}
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// apply defaults - convenient when used to configure for tests
|
||||
// in an application context
|
||||
if (mongo == null) {
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// apply defaults - convenient when used to configure for tests
|
||||
// in an application context
|
||||
if (mongo == null) {
|
||||
if (host == null) {
|
||||
logger.warn("Property host not specified. Using default configuration");
|
||||
mongo = new Mongo();
|
||||
} else {
|
||||
ServerAddress defaultOptions = new ServerAddress();
|
||||
if (mongoOptions == null)
|
||||
mongoOptions = new MongoOptions();
|
||||
if (replicaPair != null) {
|
||||
if (replicaPair.size() < 2) {
|
||||
throw new CannotGetMongoDbConnectionException("A replica pair must have two server entries");
|
||||
}
|
||||
mongo = new Mongo(replicaPair.get(0), replicaPair.get(1), mongoOptions);
|
||||
} else if (replicaSetSeeds != null) {
|
||||
mongo = new Mongo(replicaSetSeeds, mongoOptions);
|
||||
} else {
|
||||
String mongoHost = host != null ? host : defaultOptions.getHost();
|
||||
if (port != null) {
|
||||
mongo = new Mongo(new ServerAddress(mongoHost, port), mongoOptions);
|
||||
} else {
|
||||
mongo = new Mongo(mongoHost, mongoOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (host == null) {
|
||||
logger.warn("Property host not specified. Using default configuration");
|
||||
mongo = new Mongo();
|
||||
} else {
|
||||
ServerAddress defaultOptions = new ServerAddress();
|
||||
if (mongoOptions == null) mongoOptions = new MongoOptions();
|
||||
if (replicaPair != null) {
|
||||
if (replicaPair.size() < 2) {
|
||||
throw new CannotGetMongoDbConnectionException("A replica pair must have two server entries");
|
||||
}
|
||||
mongo = new Mongo(replicaPair.get(0), replicaPair.get(1), mongoOptions);
|
||||
} else if (replicaSetSeeds != null) {
|
||||
mongo = new Mongo(replicaSetSeeds, mongoOptions);
|
||||
} else {
|
||||
String mongoHost = host != null ? host : defaultOptions.getHost();
|
||||
if (port != null) {
|
||||
mongo = new Mongo(new ServerAddress(mongoHost, port), mongoOptions);
|
||||
} else {
|
||||
mongo = new Mongo(mongoHost, mongoOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
return exceptionTranslator.translateExceptionIfPossible(ex);
|
||||
}
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
return exceptionTranslator.translateExceptionIfPossible(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,495 +28,537 @@ import org.springframework.data.document.mongodb.query.Query;
|
||||
import org.springframework.data.document.mongodb.query.Update;
|
||||
|
||||
/**
|
||||
* Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}.
|
||||
* Not often used but a useful option for extensibility and testability (as it can be easily mocked, stubbed, or be
|
||||
* the target of a JDK proxy).
|
||||
*
|
||||
* Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}. Not often used but
|
||||
* a useful option for extensibility and testability (as it can be easily mocked, stubbed, or be the target of a JDK
|
||||
* proxy).
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoOperations {
|
||||
|
||||
/**
|
||||
* The collection name used for the specified class by this template.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCollectionName(Class<?> clazz);
|
||||
/**
|
||||
* The collection name used for the specified class by this template.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCollectionName(Class<?> clazz);
|
||||
|
||||
/**
|
||||
* 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 converted into Spring's DAO
|
||||
* exception hierarchy.
|
||||
*
|
||||
* @param jsonCommand a MongoDB command expressed as a JSON string.
|
||||
*/
|
||||
CommandResult executeCommand(String jsonCommand);
|
||||
/**
|
||||
* 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
|
||||
* converted into Spring's DAO exception hierarchy.
|
||||
*
|
||||
* @param jsonCommand
|
||||
* a MongoDB command expressed as a JSON string.
|
||||
*/
|
||||
CommandResult executeCommand(String jsonCommand);
|
||||
|
||||
/**
|
||||
* Execute a MongoDB command. Any errors that result from executing this command will be converted
|
||||
* into Spring's DAO exception hierarchy.
|
||||
*
|
||||
* @param command a MongoDB command
|
||||
*/
|
||||
CommandResult executeCommand(DBObject command);
|
||||
/**
|
||||
* Execute a MongoDB command. Any errors that result from executing this command will be converted into Spring's DAO
|
||||
* exception hierarchy.
|
||||
*
|
||||
* @param command
|
||||
* a MongoDB command
|
||||
*/
|
||||
CommandResult executeCommand(DBObject command);
|
||||
|
||||
/**
|
||||
* Executes a {@link DbCallback} translating any exceptions as necessary.
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T> return type
|
||||
* @param action callback object that specifies the MongoDB actions to perform on the passed in DB instance.
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T execute(DbCallback<T> action);
|
||||
/**
|
||||
* Executes a {@link DbCallback} translating any exceptions as necessary.
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T>
|
||||
* return type
|
||||
* @param action
|
||||
* callback object that specifies the MongoDB actions to perform on the passed in DB instance.
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T execute(DbCallback<T> action);
|
||||
|
||||
/**
|
||||
* Executes the given {@link CollectionCallback} on the entity collection of the specified class.
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param entityClass class that determines the collection to use
|
||||
* @param <T> return type
|
||||
* @param action callback object that specifies the MongoDB action
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T execute(Class<?> entityClass, CollectionCallback<T> action);
|
||||
/**
|
||||
* Executes the given {@link CollectionCallback} on the entity collection of the specified class.
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param entityClass
|
||||
* class that determines the collection to use
|
||||
* @param <T>
|
||||
* return type
|
||||
* @param action
|
||||
* callback object that specifies the MongoDB action
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T execute(Class<?> entityClass, CollectionCallback<T> action);
|
||||
|
||||
/**
|
||||
* Executes the given {@link CollectionCallback} on the collection of the given name.
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T> return type
|
||||
* @param collectionName the name of the collection that specifies which DBCollection instance will be passed into
|
||||
* @param action callback object that specifies the MongoDB action
|
||||
* the callback action.
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T execute(String collectionName, CollectionCallback<T> action);
|
||||
/**
|
||||
* Executes the given {@link CollectionCallback} on the collection of the given name.
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T>
|
||||
* return type
|
||||
* @param collectionName
|
||||
* the name of the collection that specifies which DBCollection instance will be passed into
|
||||
* @param action
|
||||
* callback object that specifies the MongoDB action the callback action.
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T execute(String collectionName, CollectionCallback<T> action);
|
||||
|
||||
/**
|
||||
* Executes the given {@link DbCallback} within the same connection to the database so as to ensure
|
||||
* consistency in a write heavy environment where you may read the data that you wrote. See the
|
||||
* comments on {@see <a href=http://www.mongodb.org/display/DOCS/Java+Driver+Concurrency>Java Driver Concurrency</a>}
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T> return type
|
||||
* @param action callback that specified the MongoDB actions to perform on the DB instance
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T executeInSession(DbCallback<T> action);
|
||||
/**
|
||||
* Executes the given {@link DbCallback} within the same connection to the database so as to ensure consistency in a
|
||||
* write heavy environment where you may read the data that you wrote. See the comments on {@see <a
|
||||
* href=http://www.mongodb.org/display/DOCS/Java+Driver+Concurrency>Java Driver Concurrency</a>}
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T>
|
||||
* return type
|
||||
* @param action
|
||||
* callback that specified the MongoDB actions to perform on the DB instance
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T executeInSession(DbCallback<T> action);
|
||||
|
||||
/**
|
||||
* Create an uncapped collection with the provided name.
|
||||
*
|
||||
* @param collectionName name of the collection
|
||||
* @return the created collection
|
||||
*/
|
||||
DBCollection createCollection(String collectionName);
|
||||
/**
|
||||
* Create an uncapped collection with the provided name.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection
|
||||
* @return the created collection
|
||||
*/
|
||||
DBCollection createCollection(String collectionName);
|
||||
|
||||
/**
|
||||
* Create a collect with the provided name and options.
|
||||
*
|
||||
* @param collectionName name of the collection
|
||||
* @param collectionOptions options to use when creating the collection.
|
||||
* @return the created collection
|
||||
*/
|
||||
DBCollection createCollection(String collectionName, CollectionOptions collectionOptions);
|
||||
/**
|
||||
* Create a collect with the provided name and options.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection
|
||||
* @param collectionOptions
|
||||
* options to use when creating the collection.
|
||||
* @return the created collection
|
||||
*/
|
||||
DBCollection createCollection(String collectionName, CollectionOptions collectionOptions);
|
||||
|
||||
/**
|
||||
* A set of collection names.
|
||||
*
|
||||
* @return list of collection names
|
||||
*/
|
||||
Set<String> getCollectionNames();
|
||||
/**
|
||||
* A set of collection names.
|
||||
*
|
||||
* @return list of collection names
|
||||
*/
|
||||
Set<String> getCollectionNames();
|
||||
|
||||
/**
|
||||
* Get a collection by name, creating it if it doesn't exist.
|
||||
* <p/>
|
||||
* Translate any exceptions as necessary.
|
||||
*
|
||||
* @param collectionName name of the collection
|
||||
* @return an existing collection or a newly created one.
|
||||
*/
|
||||
DBCollection getCollection(String collectionName);
|
||||
/**
|
||||
* Get a collection by name, creating it if it doesn't exist.
|
||||
* <p/>
|
||||
* Translate any exceptions as necessary.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection
|
||||
* @return an existing collection or a newly created one.
|
||||
*/
|
||||
DBCollection getCollection(String collectionName);
|
||||
|
||||
/**
|
||||
* Check to see if a collection with a given name exists.
|
||||
* <p/>
|
||||
* Translate any exceptions as necessary.
|
||||
*
|
||||
* @param collectionName name of the collection
|
||||
* @return true if a collection with the given name is found, false otherwise.
|
||||
*/
|
||||
boolean collectionExists(String collectionName);
|
||||
/**
|
||||
* Check to see if a collection with a given name exists.
|
||||
* <p/>
|
||||
* Translate any exceptions as necessary.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection
|
||||
* @return true if a collection with the given name is found, false otherwise.
|
||||
*/
|
||||
boolean collectionExists(String collectionName);
|
||||
|
||||
/**
|
||||
* Drop the collection with the given name.
|
||||
* <p/>
|
||||
* Translate any exceptions as necessary.
|
||||
*
|
||||
* @param collectionName name of the collection to drop/delete.
|
||||
*/
|
||||
void dropCollection(String collectionName);
|
||||
/**
|
||||
* Drop the collection with the given name.
|
||||
* <p/>
|
||||
* Translate any exceptions as necessary.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to drop/delete.
|
||||
*/
|
||||
void dropCollection(String collectionName);
|
||||
|
||||
/**
|
||||
* Query for a list of objects of type T from the default collection.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient
|
||||
* way to map objects since the test for class type is done in the client and not on the server.
|
||||
*
|
||||
* @param targetClass the parameterized type of the returned list
|
||||
* @return the converted collection
|
||||
*/
|
||||
<T> List<T> getCollection(Class<T> targetClass);
|
||||
/**
|
||||
* Query for a list of objects of type T from the default collection.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
||||
* to map objects since the test for class type is done in the client and not on the server.
|
||||
*
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list
|
||||
* @return the converted collection
|
||||
*/
|
||||
<T> List<T> getCollection(Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Query for a list of objects of type T from the specified collection.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient
|
||||
* way to map objects since the test for class type is done in the client and not on the server.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted collection
|
||||
*/
|
||||
<T> List<T> getCollection(String collectionName, Class<T> targetClass);
|
||||
/**
|
||||
* Query for a list of objects of type T from the specified collection.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
||||
* to map objects since the test for class type is done in the client and not on the server.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to retrieve the objects from
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @return the converted collection
|
||||
*/
|
||||
<T> List<T> getCollection(String collectionName, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Ensure that an index for the provided {@link IndexDefinition} exists for the default collection.
|
||||
* If not it will be created.
|
||||
*
|
||||
* @param entityClass class that determines the collection to use
|
||||
* @param indexDefinition
|
||||
*/
|
||||
void ensureIndex(Class<?> entityClass, IndexDefinition indexDefinition);
|
||||
/**
|
||||
* Ensure that an index for the provided {@link IndexDefinition} exists for the default collection. If not it will be
|
||||
* created.
|
||||
*
|
||||
* @param entityClass
|
||||
* class that determines the collection to use
|
||||
* @param indexDefinition
|
||||
*/
|
||||
void ensureIndex(Class<?> entityClass, IndexDefinition indexDefinition);
|
||||
|
||||
/**
|
||||
* Ensure that an index for the provided {@link IndexDefinition} exists. If not it will be
|
||||
* created.
|
||||
*
|
||||
* @param collectionName
|
||||
* @param index
|
||||
*/
|
||||
void ensureIndex(String collectionName, IndexDefinition indexDefinition);
|
||||
/**
|
||||
* Ensure that an index for the provided {@link IndexDefinition} exists. If not it will be created.
|
||||
*
|
||||
* @param collectionName
|
||||
* @param index
|
||||
*/
|
||||
void ensureIndex(String collectionName, IndexDefinition indexDefinition);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a single instance of an object
|
||||
* of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findOne(Query query, Class<T> targetClass);
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a single instance of an object of the
|
||||
* specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query
|
||||
* the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findOne(Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object
|
||||
* of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findOne(String collectionName, Query query,
|
||||
Class<T> targetClass);
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
||||
* type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to retrieve the objects from
|
||||
* @param query
|
||||
* the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findOne(String collectionName, Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the List of converted objects
|
||||
*/
|
||||
<T> List<T> find(Query query, Class<T> targetClass);
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query
|
||||
* the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @return the List of converted objects
|
||||
*/
|
||||
<T> List<T> find(Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the List of converted objects
|
||||
*/
|
||||
<T> List<T> find(String collectionName, Query query,
|
||||
Class<T> targetClass);
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to retrieve the objects from
|
||||
* @param query
|
||||
* the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @return the List of converted objects
|
||||
*/
|
||||
<T> List<T> find(String collectionName, Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param preparer allows for customization of the DBCursor used when iterating over the result set,
|
||||
* (apply limits, skips and so on).
|
||||
* @return the List of converted objects.
|
||||
*/
|
||||
<T> List<T> find(String collectionName, Query query, Class<T> targetClass, CursorPreparer preparer);
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to retrieve the objects from
|
||||
* @param query
|
||||
* the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @param preparer
|
||||
* allows for customization of the DBCursor used when iterating over the result set, (apply limits, skips and
|
||||
* so on).
|
||||
* @return the List of converted objects.
|
||||
*/
|
||||
<T> List<T> find(String collectionName, Query query, Class<T> targetClass, CursorPreparer preparer);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a single instance of an object
|
||||
* of the specified type. The first document that matches the query is returned and also removed from the
|
||||
* collection in the database.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findAndRemove(Query query, Class<T> targetClass);
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a single instance of an object of the
|
||||
* specified type. The first document that matches the query is returned and also removed from the collection in the
|
||||
* database.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query
|
||||
* the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findAndRemove(Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object
|
||||
* of the specified type. The first document that matches the query is returned and also removed from the
|
||||
* collection in the database.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findAndRemove(String collectionName, Query query,
|
||||
Class<T> targetClass);
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
||||
* type. The first document that matches the query is returned and also removed from the collection in the database.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to retrieve the objects from
|
||||
* @param query
|
||||
* the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findAndRemove(String collectionName, Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Insert the object into the default collection.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property
|
||||
* is a String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from
|
||||
* ObjectId to your property type will be handled by Spring's BeanWrapper class that leverages Spring 3.0's
|
||||
* new Type Conversion API.
|
||||
* See <a href="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">Spring 3 Type Conversion"</a>
|
||||
* for more details.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* Insert is used to initially store the object into the database.
|
||||
* To update an existing object use the save method.
|
||||
*
|
||||
* @param objectToSave the object to store in the collection.
|
||||
*/
|
||||
void insert(Object objectToSave);
|
||||
/**
|
||||
* Insert the object into the default collection.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
||||
* String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from ObjectId to your
|
||||
* property type will be handled by Spring's BeanWrapper class that leverages Spring 3.0's new Type Conversion API.
|
||||
* See <a href="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">Spring 3 Type
|
||||
* Conversion"</a> for more details.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||
*
|
||||
* @param objectToSave
|
||||
* the object to store in the collection.
|
||||
*/
|
||||
void insert(Object objectToSave);
|
||||
|
||||
/**
|
||||
* Insert the object into the specified collection.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* Insert is used to initially store the object into the
|
||||
* database. To update an existing object use the save method.
|
||||
*
|
||||
* @param collectionName name of the collection to store the object in
|
||||
* @param objectToSave the object to store in the collection
|
||||
*/
|
||||
void insert(String collectionName, Object objectToSave);
|
||||
/**
|
||||
* Insert the object into the specified collection.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to store the object in
|
||||
* @param objectToSave
|
||||
* the object to store in the collection
|
||||
*/
|
||||
void insert(String collectionName, Object objectToSave);
|
||||
|
||||
/**
|
||||
* Insert a list of objects into the default collection in a single batch write to the database.
|
||||
*
|
||||
* @param listToSave the list of objects to save.
|
||||
*/
|
||||
void insertList(List<? extends Object> listToSave);
|
||||
/**
|
||||
* Insert a list of objects into the default collection in a single batch write to the database.
|
||||
*
|
||||
* @param listToSave
|
||||
* the list of objects to save.
|
||||
*/
|
||||
void insertList(List<? extends Object> listToSave);
|
||||
|
||||
/**
|
||||
* Insert a list of objects into the specified collection in a single batch write to the database.
|
||||
*
|
||||
* @param collectionName name of the collection to store the object in
|
||||
* @param listToSave the list of objects to save.
|
||||
*/
|
||||
void insertList(String collectionName, List<? extends Object> listToSave);
|
||||
/**
|
||||
* Insert a list of objects into the specified collection in a single batch write to the database.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to store the object in
|
||||
* @param listToSave
|
||||
* the list of objects to save.
|
||||
*/
|
||||
void insertList(String collectionName, List<? extends Object> listToSave);
|
||||
|
||||
/**
|
||||
* Save the object to the default collection. This will perform an insert if the object is not already
|
||||
* present, that is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property
|
||||
* is a String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from
|
||||
* ObjectId to your property type will be handled by Spring's BeanWrapper class that leverages Spring 3.0's
|
||||
* new Type Conversion API.
|
||||
* See <a href="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">Spring 3 Type Conversion"</a>
|
||||
* for more details.
|
||||
*
|
||||
* @param objectToSave the object to store in the collection
|
||||
*/
|
||||
void save(Object objectToSave);
|
||||
/**
|
||||
* Save the object to the default collection. This will perform an insert if the object is not already present, that
|
||||
* is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
||||
* String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from ObjectId to your
|
||||
* property type will be handled by Spring's BeanWrapper class that leverages Spring 3.0's new Type Conversion API.
|
||||
* See <a href="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">Spring 3 Type
|
||||
* Conversion"</a> for more details.
|
||||
*
|
||||
* @param objectToSave
|
||||
* the object to store in the collection
|
||||
*/
|
||||
void save(Object objectToSave);
|
||||
|
||||
/**
|
||||
* Save the object to the specified collection. This will perform an insert if the object is not already
|
||||
* present, that is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property
|
||||
* is a String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from
|
||||
* ObjectId to your property type will be handled by Spring's BeanWrapper class that leverages Spring 3.0's
|
||||
* new Type Cobnversion API.
|
||||
* See <a href="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">Spring 3 Type Conversion"</a>
|
||||
* for more details.
|
||||
*
|
||||
* @param collectionName name of the collection to store the object in
|
||||
* @param objectToSave the object to store in the collection
|
||||
*/
|
||||
void save(String collectionName, Object objectToSave);
|
||||
/**
|
||||
* Save the object to the specified collection. This will perform an insert if the object is not already present, that
|
||||
* is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
||||
* String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from ObjectId to your
|
||||
* property type will be handled by Spring's BeanWrapper class that leverages Spring 3.0's new Type Cobnversion API.
|
||||
* See <a href="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">Spring 3 Type
|
||||
* Conversion"</a> for more details.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to store the object in
|
||||
* @param objectToSave
|
||||
* the object to store in the collection
|
||||
*/
|
||||
void save(String collectionName, Object objectToSave);
|
||||
|
||||
/**
|
||||
* Updates the first object that is found in the default collection that matches the query document
|
||||
* with the provided updated document.
|
||||
*
|
||||
* @param entityClass class that determines the collection to use
|
||||
* @param queryDoc the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc the update document that contains the updated object or $ operators to manipulate the
|
||||
* existing object.
|
||||
*/
|
||||
WriteResult updateFirst(Class<?> entityClass, Query query, Update update);
|
||||
/**
|
||||
* Updates the first object that is found in the default collection that matches the query document with the provided
|
||||
* updated document.
|
||||
*
|
||||
* @param entityClass
|
||||
* class that determines the collection to use
|
||||
* @param queryDoc
|
||||
* the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc
|
||||
* the update document that contains the updated object or $ operators to manipulate the existing object.
|
||||
*/
|
||||
WriteResult updateFirst(Class<?> entityClass, Query query, Update update);
|
||||
|
||||
/**
|
||||
* Updates the first object that is found in the specified collection that matches the query document criteria
|
||||
* with the provided updated document.
|
||||
*
|
||||
* @param collectionName name of the collection to update the object in
|
||||
* @param queryDoc the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc the update document that contains the updated object or $ operators to manipulate the
|
||||
* existing object.
|
||||
*/
|
||||
WriteResult updateFirst(String collectionName, Query query,
|
||||
Update update);
|
||||
/**
|
||||
* Updates the first object that is found in the specified collection that matches the query document criteria with
|
||||
* the provided updated document.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to update the object in
|
||||
* @param queryDoc
|
||||
* the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc
|
||||
* the update document that contains the updated object or $ operators to manipulate the existing object.
|
||||
*/
|
||||
WriteResult updateFirst(String collectionName, Query query, Update update);
|
||||
|
||||
/**
|
||||
* Updates all objects that are found in the default collection that matches the query document criteria
|
||||
* with the provided updated document.
|
||||
*
|
||||
* @param entityClass class that determines the collection to use
|
||||
* @param queryDoc the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc the update document that contains the updated object or $ operators to manipulate the
|
||||
* existing object.
|
||||
*/
|
||||
WriteResult updateMulti(Class<?> entityClass, Query query, Update update);
|
||||
/**
|
||||
* Updates all objects that are found in the default collection that matches the query document criteria with the
|
||||
* provided updated document.
|
||||
*
|
||||
* @param entityClass
|
||||
* class that determines the collection to use
|
||||
* @param queryDoc
|
||||
* the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc
|
||||
* the update document that contains the updated object or $ operators to manipulate the existing object.
|
||||
*/
|
||||
WriteResult updateMulti(Class<?> entityClass, Query query, Update update);
|
||||
|
||||
/**
|
||||
* Updates all objects that are found in the specified collection that matches the query document criteria
|
||||
* with the provided updated document.
|
||||
*
|
||||
* @param collectionName name of the collection to update the object in
|
||||
* @param queryDoc the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc the update document that contains the updated object or $ operators to manipulate the
|
||||
* existing object.
|
||||
*/
|
||||
WriteResult updateMulti(String collectionName, Query query,
|
||||
Update update);
|
||||
/**
|
||||
* Updates all objects that are found in the specified collection that matches the query document criteria with the
|
||||
* provided updated document.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to update the object in
|
||||
* @param queryDoc
|
||||
* the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc
|
||||
* the update document that contains the updated object or $ operators to manipulate the existing object.
|
||||
*/
|
||||
WriteResult updateMulti(String collectionName, Query query, Update update);
|
||||
|
||||
/**
|
||||
* Remove the given object from the collection by Id
|
||||
* @param object
|
||||
*/
|
||||
void remove(Object object);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Remove all documents from the default collection that match the provided query document criteria.
|
||||
*
|
||||
* @param queryDoc the query document that specifies the criteria used to remove a record
|
||||
*/
|
||||
void remove(Query query);
|
||||
|
||||
/**
|
||||
* Remove all documents from the default collection that match the provided query document criteria. The
|
||||
* Class parameter is used to help convert the Id of the object if it is present in the query.
|
||||
* @param <T>
|
||||
* @param query
|
||||
* @param targetClass
|
||||
*/
|
||||
<T> void remove(Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Remove all documents from the specified collection that match the provided query document criteria.
|
||||
*
|
||||
* @param collectionName name of the collection where the objects will removed
|
||||
* @param queryDoc the query document that specifies the criteria used to remove a record
|
||||
*/
|
||||
void remove(String collectionName, Query query);
|
||||
|
||||
/**
|
||||
* Remove all documents from the specified collection that match the provided query document criteria.
|
||||
* The Class parameter is used to help convert the Id of the object if it is present in the query.
|
||||
* @param collectionName
|
||||
* @param query
|
||||
* @param targetClass
|
||||
*/
|
||||
<T> void remove(String collectionName, Query query, Class<T> targetClass);
|
||||
/**
|
||||
* Remove the given object from the collection by Id
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
void remove(Object object);
|
||||
|
||||
/**
|
||||
* Remove all documents from the default collection that match the provided query document criteria.
|
||||
*
|
||||
* @param queryDoc
|
||||
* the query document that specifies the criteria used to remove a record
|
||||
*/
|
||||
void remove(Query query);
|
||||
|
||||
/**
|
||||
* Remove all documents from the default collection that match the provided query document criteria. The Class
|
||||
* parameter is used to help convert the Id of the object if it is present in the query.
|
||||
*
|
||||
* @param <T>
|
||||
* @param query
|
||||
* @param targetClass
|
||||
*/
|
||||
<T> void remove(Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Remove all documents from the specified collection that match the provided query document criteria.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection where the objects will removed
|
||||
* @param queryDoc
|
||||
* the query document that specifies the criteria used to remove a record
|
||||
*/
|
||||
void remove(String collectionName, Query query);
|
||||
|
||||
/**
|
||||
* Remove all documents from the specified collection that match the provided query document criteria. The Class
|
||||
* parameter is used to help convert the Id of the object if it is present in the query.
|
||||
*
|
||||
* @param collectionName
|
||||
* @param query
|
||||
* @param targetClass
|
||||
*/
|
||||
<T> void remove(String collectionName, Query query, Class<T> targetClass);
|
||||
|
||||
}
|
||||
@@ -21,114 +21,108 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* A factory bean for consruction a MongoOptions instance
|
||||
*
|
||||
*
|
||||
* @author Graeme Rocher
|
||||
*/
|
||||
public class MongoOptionsFactoryBean implements FactoryBean<MongoOptions>, InitializingBean {
|
||||
|
||||
private static final MongoOptions MONGO_OPTIONS = new MongoOptions();
|
||||
/**
|
||||
* number of connections allowed per host
|
||||
* will block if run out
|
||||
*/
|
||||
private int connectionsPerHost = MONGO_OPTIONS.connectionsPerHost;
|
||||
private static final MongoOptions MONGO_OPTIONS = new MongoOptions();
|
||||
/**
|
||||
* number of connections allowed per host will block if run out
|
||||
*/
|
||||
private int connectionsPerHost = MONGO_OPTIONS.connectionsPerHost;
|
||||
|
||||
/**
|
||||
* multiplier for connectionsPerHost for # of threads that can block
|
||||
* if connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
|
||||
* then 50 threads can block
|
||||
* more than that and an exception will be throw
|
||||
*/
|
||||
private int threadsAllowedToBlockForConnectionMultiplier = MONGO_OPTIONS.threadsAllowedToBlockForConnectionMultiplier;
|
||||
/**
|
||||
* multiplier for connectionsPerHost for # of threads that can block if connectionsPerHost is 10, and
|
||||
* threadsAllowedToBlockForConnectionMultiplier is 5, then 50 threads can block more than that and an exception will
|
||||
* be throw
|
||||
*/
|
||||
private int threadsAllowedToBlockForConnectionMultiplier = MONGO_OPTIONS.threadsAllowedToBlockForConnectionMultiplier;
|
||||
|
||||
/**
|
||||
* max wait time of a blocking thread for a connection
|
||||
*/
|
||||
private int maxWaitTime = MONGO_OPTIONS.maxWaitTime;
|
||||
/**
|
||||
* max wait time of a blocking thread for a connection
|
||||
*/
|
||||
private int maxWaitTime = MONGO_OPTIONS.maxWaitTime;
|
||||
|
||||
/**
|
||||
* connect timeout in milliseconds. 0 is default and infinite
|
||||
*/
|
||||
private int connectTimeout = MONGO_OPTIONS.connectTimeout;
|
||||
/**
|
||||
* connect timeout in milliseconds. 0 is default and infinite
|
||||
*/
|
||||
private int connectTimeout = MONGO_OPTIONS.connectTimeout;
|
||||
|
||||
/**
|
||||
* socket timeout. 0 is default and infinite
|
||||
*/
|
||||
private int socketTimeout = MONGO_OPTIONS.socketTimeout;
|
||||
/**
|
||||
* socket timeout. 0 is default and infinite
|
||||
*/
|
||||
private int socketTimeout = MONGO_OPTIONS.socketTimeout;
|
||||
|
||||
/**
|
||||
* this controls whether or not on a connect, the system retries automatically
|
||||
*/
|
||||
private boolean autoConnectRetry = MONGO_OPTIONS.autoConnectRetry;
|
||||
/**
|
||||
* this controls whether or not on a connect, the system retries automatically
|
||||
*/
|
||||
private boolean autoConnectRetry = MONGO_OPTIONS.autoConnectRetry;
|
||||
|
||||
/**
|
||||
* number of connections allowed per host will block if run out
|
||||
*/
|
||||
public void setConnectionsPerHost(int connectionsPerHost) {
|
||||
this.connectionsPerHost = connectionsPerHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* number of connections allowed per host
|
||||
* will block if run out
|
||||
*/
|
||||
public void setConnectionsPerHost(int connectionsPerHost) {
|
||||
this.connectionsPerHost = connectionsPerHost;
|
||||
}
|
||||
/**
|
||||
* multiplier for connectionsPerHost for # of threads that can block if connectionsPerHost is 10, and
|
||||
* threadsAllowedToBlockForConnectionMultiplier is 5, then 50 threads can block more than that and an exception will
|
||||
* be throw
|
||||
*/
|
||||
public void setThreadsAllowedToBlockForConnectionMultiplier(int threadsAllowedToBlockForConnectionMultiplier) {
|
||||
this.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* multiplier for connectionsPerHost for # of threads that can block
|
||||
* if connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
|
||||
* then 50 threads can block
|
||||
* more than that and an exception will be throw
|
||||
*/
|
||||
public void setThreadsAllowedToBlockForConnectionMultiplier(
|
||||
int threadsAllowedToBlockForConnectionMultiplier) {
|
||||
this.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
|
||||
}
|
||||
/**
|
||||
* max wait time of a blocking thread for a connection
|
||||
*/
|
||||
public void setMaxWaitTime(int maxWaitTime) {
|
||||
this.maxWaitTime = maxWaitTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* max wait time of a blocking thread for a connection
|
||||
*/
|
||||
public void setMaxWaitTime(int maxWaitTime) {
|
||||
this.maxWaitTime = maxWaitTime;
|
||||
}
|
||||
/**
|
||||
* connect timeout in milliseconds. 0 is default and infinite
|
||||
*/
|
||||
public void setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* connect timeout in milliseconds. 0 is default and infinite
|
||||
*/
|
||||
public void setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
/**
|
||||
* socket timeout. 0 is default and infinite
|
||||
*/
|
||||
public void setSocketTimeout(int socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* socket timeout. 0 is default and infinite
|
||||
*/
|
||||
public void setSocketTimeout(int socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
/**
|
||||
* this controls whether or not on a connect, the system retries automatically
|
||||
*/
|
||||
public void setAutoConnectRetry(boolean autoConnectRetry) {
|
||||
this.autoConnectRetry = autoConnectRetry;
|
||||
}
|
||||
|
||||
/**
|
||||
* this controls whether or not on a connect, the system retries automatically
|
||||
*/
|
||||
public void setAutoConnectRetry(boolean autoConnectRetry) {
|
||||
this.autoConnectRetry = autoConnectRetry;
|
||||
}
|
||||
public void afterPropertiesSet() {
|
||||
MONGO_OPTIONS.connectionsPerHost = connectionsPerHost;
|
||||
MONGO_OPTIONS.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
|
||||
MONGO_OPTIONS.maxWaitTime = maxWaitTime;
|
||||
MONGO_OPTIONS.connectTimeout = connectTimeout;
|
||||
MONGO_OPTIONS.socketTimeout = socketTimeout;
|
||||
MONGO_OPTIONS.autoConnectRetry = autoConnectRetry;
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
MONGO_OPTIONS.connectionsPerHost = connectionsPerHost;
|
||||
MONGO_OPTIONS.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
|
||||
MONGO_OPTIONS.maxWaitTime = maxWaitTime;
|
||||
MONGO_OPTIONS.connectTimeout = connectTimeout;
|
||||
MONGO_OPTIONS.socketTimeout = socketTimeout;
|
||||
MONGO_OPTIONS.autoConnectRetry = autoConnectRetry;
|
||||
}
|
||||
|
||||
}
|
||||
public MongoOptions getObject() {
|
||||
return MONGO_OPTIONS;
|
||||
}
|
||||
|
||||
public MongoOptions getObject() {
|
||||
return MONGO_OPTIONS;
|
||||
}
|
||||
public Class<?> getObjectType() {
|
||||
return MongoOptions.class;
|
||||
}
|
||||
|
||||
public Class<?> getObjectType() {
|
||||
return MongoOptions.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,217 +29,216 @@ import org.springframework.util.ReflectionUtils;
|
||||
/**
|
||||
* An iterable of {@link MongoPropertyDescriptor}s that allows dedicated access to the {@link MongoPropertyDescriptor}
|
||||
* that captures the id-property.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoPropertyDescriptors implements Iterable<MongoPropertyDescriptors.MongoPropertyDescriptor> {
|
||||
|
||||
private final Collection<MongoPropertyDescriptors.MongoPropertyDescriptor> descriptors;
|
||||
private final MongoPropertyDescriptors.MongoPropertyDescriptor idDescriptor;
|
||||
private final Collection<MongoPropertyDescriptors.MongoPropertyDescriptor> descriptors;
|
||||
private final MongoPropertyDescriptors.MongoPropertyDescriptor idDescriptor;
|
||||
|
||||
/**
|
||||
* Creates the {@link MongoPropertyDescriptors} for the given type.
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
public MongoPropertyDescriptors(Class<?> type) {
|
||||
/**
|
||||
* Creates the {@link MongoPropertyDescriptors} for the given type.
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
public MongoPropertyDescriptors(Class<?> type) {
|
||||
|
||||
Assert.notNull(type);
|
||||
Set<MongoPropertyDescriptors.MongoPropertyDescriptor> descriptors = new HashSet<MongoPropertyDescriptors.MongoPropertyDescriptor>();
|
||||
MongoPropertyDescriptors.MongoPropertyDescriptor idDesciptor = null;
|
||||
Assert.notNull(type);
|
||||
Set<MongoPropertyDescriptors.MongoPropertyDescriptor> descriptors = new HashSet<MongoPropertyDescriptors.MongoPropertyDescriptor>();
|
||||
MongoPropertyDescriptors.MongoPropertyDescriptor idDesciptor = null;
|
||||
|
||||
for (PropertyDescriptor candidates : BeanUtils.getPropertyDescriptors(type)) {
|
||||
MongoPropertyDescriptor descriptor = new MongoPropertyDescriptors.MongoPropertyDescriptor(candidates, type);
|
||||
descriptors.add(descriptor);
|
||||
if (descriptor.isIdProperty()) {
|
||||
idDesciptor = descriptor;
|
||||
}
|
||||
}
|
||||
for (PropertyDescriptor candidates : BeanUtils.getPropertyDescriptors(type)) {
|
||||
MongoPropertyDescriptor descriptor = new MongoPropertyDescriptors.MongoPropertyDescriptor(candidates, type);
|
||||
descriptors.add(descriptor);
|
||||
if (descriptor.isIdProperty()) {
|
||||
idDesciptor = descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
this.descriptors = Collections.unmodifiableSet(descriptors);
|
||||
this.idDescriptor = idDesciptor;
|
||||
}
|
||||
this.descriptors = Collections.unmodifiableSet(descriptors);
|
||||
this.idDescriptor = idDesciptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MongoPropertyDescriptor} for the id property.
|
||||
*
|
||||
* @return the idDescriptor
|
||||
*/
|
||||
public MongoPropertyDescriptors.MongoPropertyDescriptor getIdDescriptor() {
|
||||
return idDescriptor;
|
||||
}
|
||||
/**
|
||||
* Returns the {@link MongoPropertyDescriptor} for the id property.
|
||||
*
|
||||
* @return the idDescriptor
|
||||
*/
|
||||
public MongoPropertyDescriptors.MongoPropertyDescriptor getIdDescriptor() {
|
||||
return idDescriptor;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<MongoPropertyDescriptors.MongoPropertyDescriptor> iterator() {
|
||||
return descriptors.iterator();
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<MongoPropertyDescriptors.MongoPropertyDescriptor> iterator() {
|
||||
return descriptors.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple value object to have a more suitable abstraction for MongoDB specific property handling.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class MongoPropertyDescriptor {
|
||||
/**
|
||||
* Simple value object to have a more suitable abstraction for MongoDB specific property handling.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class MongoPropertyDescriptor {
|
||||
|
||||
public static Collection<Class<?>> SUPPORTED_ID_CLASSES;
|
||||
public static Collection<Class<?>> SUPPORTED_ID_CLASSES;
|
||||
|
||||
static {
|
||||
Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
classes.add(ObjectId.class);
|
||||
classes.add(String.class);
|
||||
classes.add(BigInteger.class);
|
||||
SUPPORTED_ID_CLASSES = Collections.unmodifiableCollection(classes);
|
||||
}
|
||||
static {
|
||||
Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
classes.add(ObjectId.class);
|
||||
classes.add(String.class);
|
||||
classes.add(BigInteger.class);
|
||||
SUPPORTED_ID_CLASSES = Collections.unmodifiableCollection(classes);
|
||||
}
|
||||
|
||||
private static final String ID_PROPERTY = "id";
|
||||
static final String ID_KEY = "_id";
|
||||
private static final String ID_PROPERTY = "id";
|
||||
static final String ID_KEY = "_id";
|
||||
|
||||
private final PropertyDescriptor delegate;
|
||||
private final Class<?> owningType;
|
||||
private final PropertyDescriptor delegate;
|
||||
private final Class<?> owningType;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoPropertyDescriptor} for the given {@link PropertyDescriptor}.
|
||||
*
|
||||
* @param descriptor
|
||||
* @param owningType
|
||||
*/
|
||||
public MongoPropertyDescriptor(PropertyDescriptor descriptor, Class<?> owningType) {
|
||||
Assert.notNull(descriptor);
|
||||
this.delegate = descriptor;
|
||||
this.owningType = owningType;
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link MongoPropertyDescriptor} for the given {@link PropertyDescriptor}.
|
||||
*
|
||||
* @param descriptor
|
||||
* @param owningType
|
||||
*/
|
||||
public MongoPropertyDescriptor(PropertyDescriptor descriptor, Class<?> owningType) {
|
||||
Assert.notNull(descriptor);
|
||||
this.delegate = descriptor;
|
||||
this.owningType = owningType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the property is the id-property. Will be identified by name for now ({@value #ID_PROPERTY}).
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isIdProperty() {
|
||||
return ID_PROPERTY.equals(delegate.getName()) || ID_KEY.equals(delegate.getName());
|
||||
}
|
||||
/**
|
||||
* Returns whether the property is the id-property. Will be identified by name for now ({@value #ID_PROPERTY}).
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isIdProperty() {
|
||||
return ID_PROPERTY.equals(delegate.getName()) || ID_KEY.equals(delegate.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the property is of one of the supported id types. Currently we support {@link String},
|
||||
* {@link ObjectId} and {@link BigInteger}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isOfIdType() {
|
||||
return SUPPORTED_ID_CLASSES.contains(delegate.getPropertyType());
|
||||
}
|
||||
/**
|
||||
* Returns whether the property is of one of the supported id types. Currently we support {@link String},
|
||||
* {@link ObjectId} and {@link BigInteger}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isOfIdType() {
|
||||
return SUPPORTED_ID_CLASSES.contains(delegate.getPropertyType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key that shall be used for mapping. Will return {@value #ID_KEY} for the id property and the
|
||||
* plain name for all other ones.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getKeyToMap() {
|
||||
return isIdProperty() ? ID_KEY : delegate.getName();
|
||||
}
|
||||
/**
|
||||
* Returns the key that shall be used for mapping. Will return {@value #ID_KEY} for the id property and the plain
|
||||
* name for all other ones.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getKeyToMap() {
|
||||
return isIdProperty() ? ID_KEY : delegate.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the property.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
/**
|
||||
* Returns the name of the property.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the underlying property is actually mappable. By default this will exclude the
|
||||
* {@literal class} property and only include properties with a getter.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isMappable() {
|
||||
|
||||
boolean isNotClassAttribute = !delegate.getName().equals("class");
|
||||
boolean hasGetter = delegate.getReadMethod() != null;
|
||||
boolean hasField = ReflectionUtils.findField(owningType, delegate.getName()) != null;
|
||||
|
||||
return isNotClassAttribute && hasGetter && hasField;
|
||||
}
|
||||
/**
|
||||
* Returns whether the underlying property is actually mappable. By default this will exclude the {@literal class}
|
||||
* property and only include properties with a getter.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isMappable() {
|
||||
|
||||
/**
|
||||
* Returns the plain property type.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Class<?> getPropertyType() {
|
||||
return delegate.getPropertyType();
|
||||
}
|
||||
boolean isNotClassAttribute = !delegate.getName().equals("class");
|
||||
boolean hasGetter = delegate.getReadMethod() != null;
|
||||
boolean hasField = ReflectionUtils.findField(owningType, delegate.getName()) != null;
|
||||
|
||||
/**
|
||||
* Returns the type type to be set. Will return the setter method's type and fall back to the getter method's
|
||||
* return type in case no setter is available. Useful for further (generics) inspection.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Type getTypeToSet() {
|
||||
return isNotClassAttribute && hasGetter && hasField;
|
||||
}
|
||||
|
||||
Method method = delegate.getWriteMethod();
|
||||
return method == null ? delegate.getReadMethod().getGenericReturnType()
|
||||
: method.getGenericParameterTypes()[0];
|
||||
}
|
||||
/**
|
||||
* Returns the plain property type.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Class<?> getPropertyType() {
|
||||
return delegate.getPropertyType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whther we describe a {@link Map}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isMap() {
|
||||
return Map.class.isAssignableFrom(getPropertyType());
|
||||
}
|
||||
/**
|
||||
* Returns the type type to be set. Will return the setter method's type and fall back to the getter method's return
|
||||
* type in case no setter is available. Useful for further (generics) inspection.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Type getTypeToSet() {
|
||||
|
||||
/**
|
||||
* Returns whether the descriptor is for a collection.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isCollection() {
|
||||
return Collection.class.isAssignableFrom(getPropertyType());
|
||||
}
|
||||
Method method = delegate.getWriteMethod();
|
||||
return method == null ? delegate.getReadMethod().getGenericReturnType() : method.getGenericParameterTypes()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the descriptor is for an {@link Enum}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEnum() {
|
||||
return Enum.class.isAssignableFrom(getPropertyType());
|
||||
}
|
||||
/**
|
||||
* Returns whther we describe a {@link Map}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isMap() {
|
||||
return Map.class.isAssignableFrom(getPropertyType());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
MongoPropertyDescriptor that = (MongoPropertyDescriptor) obj;
|
||||
return that.delegate.equals(this.delegate);
|
||||
}
|
||||
/**
|
||||
* Returns whether the descriptor is for a collection.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isCollection() {
|
||||
return Collection.class.isAssignableFrom(getPropertyType());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns whether the descriptor is for an {@link Enum}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEnum() {
|
||||
return Enum.class.isAssignableFrom(getPropertyType());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
MongoPropertyDescriptor that = (MongoPropertyDescriptor) obj;
|
||||
return that.delegate.equals(this.delegate);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,22 +19,25 @@ import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* A MongoWriter is responsible for converting a native MongoDB DBObject to an object of type T.
|
||||
*
|
||||
* @param <T> the type of the object to convert from a DBObject
|
||||
*
|
||||
* @param <T>
|
||||
* the type of the object to convert from a DBObject
|
||||
* @author Mark Pollack
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoReader<T> {
|
||||
|
||||
/**
|
||||
* Ready from the native MongoDB DBObject representation to an instance of the class T. The given type has to be the
|
||||
* starting point for marshalling the {@link DBObject} into it. So in case there's no real valid data inside
|
||||
* {@link DBObject} for the given type, just return an empty instance of the given type.
|
||||
*
|
||||
* @param clazz the type of the return value
|
||||
* @param dbo theDBObject
|
||||
* @return the converted object
|
||||
*/
|
||||
<S extends T> S read(Class<S> clazz, DBObject dbo);
|
||||
/**
|
||||
* Ready from the native MongoDB DBObject representation to an instance of the class T. The given type has to be the
|
||||
* starting point for marshalling the {@link DBObject} into it. So in case there's no real valid data inside
|
||||
* {@link DBObject} for the given type, just return an empty instance of the given type.
|
||||
*
|
||||
* @param clazz
|
||||
* the type of the return value
|
||||
* @param dbo
|
||||
* theDBObject
|
||||
* @return the converted object
|
||||
*/
|
||||
<S extends T> S read(Class<S> clazz, DBObject dbo);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@ import org.springframework.transaction.support.ResourceHolderSynchronization;
|
||||
|
||||
class MongoSynchronization extends ResourceHolderSynchronization<ResourceHolder, Object> {
|
||||
|
||||
public MongoSynchronization(ResourceHolder resourceHolder,
|
||||
Object resourceKey) {
|
||||
super(resourceHolder, resourceKey);
|
||||
}
|
||||
public MongoSynchronization(ResourceHolder resourceHolder, Object resourceKey) {
|
||||
super(resourceHolder, resourceKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Primary implementation of {@link MongoOperations}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Graeme Rocher
|
||||
* @author Mark Pollack
|
||||
@@ -110,7 +110,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Constructor used for a basic template configuration
|
||||
*
|
||||
*
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
*/
|
||||
@@ -119,8 +119,9 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for a template configuration with a custom {@link org.springframework.data.document.mongodb.convert.MongoConverter}
|
||||
*
|
||||
* Constructor used for a template configuration with a custom
|
||||
* {@link org.springframework.data.document.mongodb.convert.MongoConverter}
|
||||
*
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
* @param mongoConverter
|
||||
@@ -130,16 +131,17 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for a template configuration with a custom {@link MongoConverter}
|
||||
* and with a specific {@link com.mongodb.WriteConcern} to be used for all database write operations
|
||||
*
|
||||
* Constructor used for a template configuration with a custom {@link MongoConverter} and with a specific
|
||||
* {@link com.mongodb.WriteConcern} to be used for all database write operations
|
||||
*
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
* @param mongoConverter
|
||||
* @param writeConcern
|
||||
* @param writeResultChecking
|
||||
*/
|
||||
MongoTemplate(Mongo mongo, String databaseName, MongoConverter mongoConverter, WriteConcern writeConcern, WriteResultChecking writeResultChecking) {
|
||||
MongoTemplate(Mongo mongo, String databaseName, MongoConverter mongoConverter, WriteConcern writeConcern,
|
||||
WriteResultChecking writeResultChecking) {
|
||||
|
||||
Assert.notNull(mongo);
|
||||
Assert.notNull(databaseName);
|
||||
@@ -174,8 +176,9 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Sets the username to use to connect to the Mongo database
|
||||
*
|
||||
* @param username The username to use
|
||||
*
|
||||
* @param username
|
||||
* The username to use
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
@@ -183,8 +186,9 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Sets the password to use to authenticate with the Mongo database.
|
||||
*
|
||||
* @param password The password to use
|
||||
*
|
||||
* @param password
|
||||
* The password to use
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
|
||||
@@ -193,7 +197,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Sets the database name to be used.
|
||||
*
|
||||
*
|
||||
* @param databaseName
|
||||
*/
|
||||
public void setDatabaseName(String databaseName) {
|
||||
@@ -203,7 +207,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Returns the default {@link org.springframework.data.document.mongodb.convert.MongoConverter}.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public MongoConverter getConverter() {
|
||||
@@ -238,10 +242,9 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
String error = result.getErrorMessage();
|
||||
if (error != null) {
|
||||
// TODO: allow configuration of logging level / throw
|
||||
// throw new InvalidDataAccessApiUsageException("Command execution of " +
|
||||
// command.toString() + " failed: " + error);
|
||||
LOGGER.warn("Command execution of " +
|
||||
command.toString() + " failed: " + error);
|
||||
// throw new InvalidDataAccessApiUsageException("Command execution of " +
|
||||
// command.toString() + " failed: " + error);
|
||||
LOGGER.warn("Command execution of " + command.toString() + " failed: " + error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -285,18 +288,23 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Central callback executing method to do queries against the datastore that requires reading a single object from a
|
||||
* collection of objects. It will take the following steps <ol> <li>Execute the given {@link ConnectionCallback} for a
|
||||
* {@link DBObject}.</li> <li>Apply the given
|
||||
* {@link DbObjectCallback} to each of the {@link DBObject}s to obtain the result.</li> <ol>
|
||||
*
|
||||
* collection of objects. It will take the following steps
|
||||
* <ol>
|
||||
* <li>Execute the given {@link ConnectionCallback} for a {@link DBObject}.</li>
|
||||
* <li>Apply the given {@link DbObjectCallback} to each of the {@link DBObject}s to obtain the result.</li>
|
||||
* <ol>
|
||||
*
|
||||
* @param <T>
|
||||
* @param collectionCallback the callback to retrieve the {@link DBObject} with
|
||||
* @param objectCallback the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type
|
||||
* @param collectionName the collection to be queried
|
||||
* @param collectionCallback
|
||||
* the callback to retrieve the {@link DBObject} with
|
||||
* @param objectCallback
|
||||
* the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type
|
||||
* @param collectionName
|
||||
* the collection to be queried
|
||||
* @return
|
||||
*/
|
||||
private <T> T execute(CollectionCallback<DBObject> collectionCallback,
|
||||
DbObjectCallback<T> objectCallback, String collectionName) {
|
||||
private <T> T execute(CollectionCallback<DBObject> collectionCallback, DbObjectCallback<T> objectCallback,
|
||||
String collectionName) {
|
||||
|
||||
try {
|
||||
T result = objectCallback.doWith(collectionCallback.doInCollection(getCollection(collectionName)));
|
||||
@@ -308,20 +316,28 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Central callback executing method to do queries against the datastore that requires reading a collection of
|
||||
* objects. It will take the following steps <ol> <li>Execute the given {@link ConnectionCallback} for a
|
||||
* {@link DBCursor}.</li> <li>Prepare that {@link DBCursor} with the given {@link CursorPreparer} (will be skipped
|
||||
* if {@link CursorPreparer} is {@literal null}</li> <li>Iterate over the {@link DBCursor} and applies the given
|
||||
* {@link DbObjectCallback} to each of the {@link DBObject}s collecting the actual result {@link List}.</li> <ol>
|
||||
*
|
||||
* objects. It will take the following steps
|
||||
* <ol>
|
||||
* <li>Execute the given {@link ConnectionCallback} for a {@link DBCursor}.</li>
|
||||
* <li>Prepare that {@link DBCursor} with the given {@link CursorPreparer} (will be skipped if {@link CursorPreparer}
|
||||
* is {@literal null}</li>
|
||||
* <li>Iterate over the {@link DBCursor} and applies the given {@link DbObjectCallback} to each of the
|
||||
* {@link DBObject}s collecting the actual result {@link List}.</li>
|
||||
* <ol>
|
||||
*
|
||||
* @param <T>
|
||||
* @param collectionCallback the callback to retrieve the {@link DBCursor} with
|
||||
* @param preparer the {@link CursorPreparer} to potentially modify the {@link DBCursor} before ireating over it
|
||||
* @param objectCallback the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type
|
||||
* @param collectionName the collection to be queried
|
||||
* @param collectionCallback
|
||||
* the callback to retrieve the {@link DBCursor} with
|
||||
* @param preparer
|
||||
* the {@link CursorPreparer} to potentially modify the {@link DBCursor} before ireating over it
|
||||
* @param objectCallback
|
||||
* the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type
|
||||
* @param collectionName
|
||||
* the collection to be queried
|
||||
* @return
|
||||
*/
|
||||
private <T> List<T> executeEach(CollectionCallback<DBCursor> collectionCallback, CursorPreparer preparer,
|
||||
DbObjectCallback<T> objectCallback, String collectionName) {
|
||||
DbObjectCallback<T> objectCallback, String collectionName) {
|
||||
|
||||
try {
|
||||
DBCursor cursor = collectionCallback.doInCollection(getCollection(collectionName));
|
||||
@@ -384,7 +400,6 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoOperations#collectionExists(java.lang.String)
|
||||
*/
|
||||
@@ -435,8 +450,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
return findOne(determineCollectionName(targetClass), query, targetClass);
|
||||
}
|
||||
|
||||
public <T> T findOne(String collectionName, Query query,
|
||||
Class<T> targetClass) {
|
||||
public <T> T findOne(String collectionName, Query query, Class<T> targetClass) {
|
||||
return doFindOne(collectionName, query.getQueryObject(), query.getFieldsObject(), targetClass);
|
||||
}
|
||||
|
||||
@@ -473,8 +487,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), targetClass, cursorPreparer);
|
||||
}
|
||||
|
||||
public <T> List<T> find(String collectionName, Query query,
|
||||
Class<T> targetClass, CursorPreparer preparer) {
|
||||
public <T> List<T> find(String collectionName, Query query, Class<T> targetClass, CursorPreparer preparer) {
|
||||
return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), targetClass, preparer);
|
||||
}
|
||||
|
||||
@@ -485,9 +498,9 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
return findAndRemove(determineCollectionName(targetClass), query, targetClass);
|
||||
}
|
||||
|
||||
public <T> T findAndRemove(String collectionName, Query query,
|
||||
Class<T> targetClass) {
|
||||
return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(), targetClass);
|
||||
public <T> T findAndRemove(String collectionName, Query query, Class<T> targetClass) {
|
||||
return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(),
|
||||
targetClass);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -538,8 +551,8 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(o.getClass());
|
||||
if (entity == null) {
|
||||
throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class " +
|
||||
o.getClass().getName());
|
||||
throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class "
|
||||
+ o.getClass().getName());
|
||||
}
|
||||
String collection = entity.getCollection();
|
||||
|
||||
@@ -608,15 +621,14 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
maybeEmitEvent(new AfterSaveEvent<T>(objectToSave, dbDoc));
|
||||
}
|
||||
|
||||
|
||||
protected Object insertDBObject(String collectionName, final DBObject dbDoc) {
|
||||
|
||||
// DATADOC-95: This will prevent null objects from being saved.
|
||||
//if (dbDoc.keySet().isEmpty()) {
|
||||
//return null;
|
||||
//}
|
||||
// if (dbDoc.keySet().isEmpty()) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
//TODO: Need to move this to more central place
|
||||
// TODO: Need to move this to more central place
|
||||
if (dbDoc.containsField("_id")) {
|
||||
if (dbDoc.get("_id") instanceof String) {
|
||||
ObjectId oid = convertIdValue(this.mongoConverter, dbDoc.get("_id"));
|
||||
@@ -646,7 +658,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
//TODO: Need to move this to more central place
|
||||
// TODO: Need to move this to more central place
|
||||
for (DBObject dbDoc : dbDocList) {
|
||||
if (dbDoc.containsField("_id")) {
|
||||
if (dbDoc.get("_id") instanceof String) {
|
||||
@@ -690,7 +702,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
return null;
|
||||
}
|
||||
|
||||
//TODO: Need to move this to more central place
|
||||
// TODO: Need to move this to more central place
|
||||
if (dbDoc.containsField("_id")) {
|
||||
if (dbDoc.get("_id") instanceof String) {
|
||||
ObjectId oid = convertIdValue(this.mongoConverter, dbDoc.get("_id"));
|
||||
@@ -742,12 +754,8 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
return doUpdate(collectionName, query, update, null, false, true);
|
||||
}
|
||||
|
||||
protected WriteResult doUpdate(final String collectionName,
|
||||
final Query query,
|
||||
final Update update,
|
||||
final Class<?> entityClass,
|
||||
final boolean upsert,
|
||||
final boolean multi) {
|
||||
protected WriteResult doUpdate(final String collectionName, final Query query, final Update update,
|
||||
final Class<?> entityClass, final boolean upsert, final boolean multi) {
|
||||
|
||||
return execute(collectionName, new CollectionCallback<WriteResult>() {
|
||||
public WriteResult doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
@@ -773,7 +781,8 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("calling update using query: " + queryObj + " and update: " + updateObj + " in collection: " + collectionName);
|
||||
LOGGER.debug("calling update using query: " + queryObj + " and update: " + updateObj + " in collection: "
|
||||
+ collectionName);
|
||||
}
|
||||
|
||||
WriteResult wr;
|
||||
@@ -841,7 +850,6 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
remove(collectionName, query, null);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoOperations#getCollection(java.lang.Class)
|
||||
*/
|
||||
@@ -875,7 +883,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Create the specified collection using the provided options
|
||||
*
|
||||
*
|
||||
* @param collectionName
|
||||
* @param collectionOptions
|
||||
* @return the collection that was created
|
||||
@@ -894,11 +902,15 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to an object using the template's converter
|
||||
* <p/>
|
||||
* The query document is specified as a standard DBObject and so is the fields specification.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query document that specifies the criteria used to find a record
|
||||
* @param fields the document that specifies the fields to be returned
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to retrieve the objects from
|
||||
* @param query
|
||||
* the query document that specifies the criteria used to find a record
|
||||
* @param fields
|
||||
* the document that specifies the fields to be returned
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @return the List of converted objects.
|
||||
*/
|
||||
protected <T> T doFindOne(String collectionName, DBObject query, DBObject fields, Class<T> targetClass) {
|
||||
@@ -906,63 +918,70 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(targetClass);
|
||||
DBObject mappedQuery = mapper.getMappedObject(query, entity);
|
||||
|
||||
return execute(new FindOneCallback(mappedQuery, fields),
|
||||
new ReadDbObjectCallback<T>(readerToUse, targetClass),
|
||||
return execute(new FindOneCallback(mappedQuery, fields), new ReadDbObjectCallback<T>(readerToUse, targetClass),
|
||||
collectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query document is specified as a standard DBObject and so is the fields specification.
|
||||
* <p/>
|
||||
* Can be overridden by subclasses.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query document that specifies the criteria used to find a record
|
||||
* @param fields the document that specifies the fields to be returned
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param preparer allows for customization of the DBCursor used when iterating over the result set,
|
||||
* (apply limits, skips and so on).
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to retrieve the objects from
|
||||
* @param query
|
||||
* the query document that specifies the criteria used to find a record
|
||||
* @param fields
|
||||
* the document that specifies the fields to be returned
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @param preparer
|
||||
* allows for customization of the DBCursor used when iterating over the result set, (apply limits, skips and
|
||||
* so on).
|
||||
* @return the List of converted objects.
|
||||
*/
|
||||
protected <T> List<T> doFind(String collectionName, DBObject query, DBObject fields, Class<T> targetClass, CursorPreparer preparer) {
|
||||
protected <T> List<T> doFind(String collectionName, DBObject query, DBObject fields, Class<T> targetClass,
|
||||
CursorPreparer preparer) {
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(targetClass);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + targetClass + " in collection: " + collectionName);
|
||||
LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + targetClass
|
||||
+ " in collection: " + collectionName);
|
||||
}
|
||||
return executeEach(new FindCallback(mapper.getMappedObject(query, entity), fields),
|
||||
preparer,
|
||||
new ReadDbObjectCallback<T>(mongoConverter, targetClass),
|
||||
collectionName);
|
||||
return executeEach(new FindCallback(mapper.getMappedObject(query, entity), fields), preparer,
|
||||
new ReadDbObjectCallback<T>(mongoConverter, targetClass), collectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a List using the template's converter.
|
||||
* <p/>
|
||||
* The query document is specified as a standard DBObject and so is the fields specification.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query document that specifies the criteria used to find a record
|
||||
* @param fields the document that specifies the fields to be returned
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param reader the MongoReader to convert from DBObject to an object.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to retrieve the objects from
|
||||
* @param query
|
||||
* the query document that specifies the criteria used to find a record
|
||||
* @param fields
|
||||
* the document that specifies the fields to be returned
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @param reader
|
||||
* the MongoReader to convert from DBObject to an object.
|
||||
* @return the List of converted objects.
|
||||
*/
|
||||
protected <T> List<T> doFind(String collectionName, DBObject query, DBObject fields, Class<T> targetClass) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + targetClass + " in collection: " + collectionName);
|
||||
LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + targetClass
|
||||
+ " in collection: " + collectionName);
|
||||
}
|
||||
MongoReader<? super T> readerToUse = this.mongoConverter;
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(targetClass);
|
||||
return executeEach(new FindCallback(mapper.getMappedObject(query, entity), fields),
|
||||
null,
|
||||
new ReadDbObjectCallback<T>(readerToUse, targetClass),
|
||||
collectionName);
|
||||
return executeEach(new FindCallback(mapper.getMappedObject(query, entity), fields), null,
|
||||
new ReadDbObjectCallback<T>(readerToUse, targetClass), collectionName);
|
||||
}
|
||||
|
||||
protected DBObject convertToDbObject(CollectionOptions collectionOptions) {
|
||||
@@ -986,22 +1005,27 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
* The first document that matches the query is returned and also removed from the collection in the database.
|
||||
* <p/>
|
||||
* The query document is specified as a standard DBObject and so is the fields specification.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query document that specifies the criteria used to find a record
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param reader the MongoReader to convert from DBObject to an object.
|
||||
*
|
||||
* @param collectionName
|
||||
* name of the collection to retrieve the objects from
|
||||
* @param query
|
||||
* the query document that specifies the criteria used to find a record
|
||||
* @param targetClass
|
||||
* the parameterized type of the returned list.
|
||||
* @param reader
|
||||
* the MongoReader to convert from DBObject to an object.
|
||||
* @return the List of converted objects.
|
||||
*/
|
||||
protected <T> T doFindAndRemove(String collectionName, DBObject query, DBObject fields, DBObject sort, Class<T> targetClass) {
|
||||
protected <T> T doFindAndRemove(String collectionName, DBObject query, DBObject fields, DBObject sort,
|
||||
Class<T> targetClass) {
|
||||
MongoReader<? super T> readerToUse = this.mongoConverter;
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("findAndRemove using query: " + query + " fields: " + fields + " sort: " + sort + " for class: " + targetClass + " in collection: " + collectionName);
|
||||
LOGGER.debug("findAndRemove using query: " + query + " fields: " + fields + " sort: " + sort + " for class: "
|
||||
+ targetClass + " in collection: " + collectionName);
|
||||
}
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(targetClass);
|
||||
return execute(new FindAndRemoveCallback(mapper.getMappedObject(query, entity), fields, sort),
|
||||
new ReadDbObjectCallback<T>(readerToUse, targetClass),
|
||||
collectionName);
|
||||
new ReadDbObjectCallback<T>(readerToUse, targetClass), collectionName);
|
||||
}
|
||||
|
||||
protected Object getIdValue(Object object) {
|
||||
@@ -1024,7 +1048,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Populates the id property of the saved object, if it's not set already.
|
||||
*
|
||||
*
|
||||
* @param savedObject
|
||||
* @param id
|
||||
*/
|
||||
@@ -1051,10 +1075,10 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes the id key if it is found in he query. Any 'id' keys will be replaced with '_id' and the value converted
|
||||
* to an ObjectId if possible. This conversion should match the way that the id fields are converted during read
|
||||
* operations.
|
||||
*
|
||||
* Substitutes the id key if it is found in he query. Any 'id' keys will be replaced with '_id' and the value
|
||||
* converted to an ObjectId if possible. This conversion should match the way that the id fields are converted during
|
||||
* read operations.
|
||||
*
|
||||
* @param query
|
||||
* @param targetClass
|
||||
* @param reader
|
||||
@@ -1087,7 +1111,8 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
// no property descriptor for this key - try the other
|
||||
try {
|
||||
String theOtherIdKey = "id".equals(idKey) ? "_id" : "id";
|
||||
MongoPropertyDescriptor mpd2 = new MongoPropertyDescriptor(new PropertyDescriptor(theOtherIdKey, targetClass), targetClass);
|
||||
MongoPropertyDescriptor mpd2 = new MongoPropertyDescriptor(new PropertyDescriptor(theOtherIdKey, targetClass),
|
||||
targetClass);
|
||||
descriptor = mpd2;
|
||||
} catch (IntrospectionException e2) {
|
||||
// no property descriptor for this key either - bail
|
||||
@@ -1109,8 +1134,8 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
}
|
||||
}
|
||||
if (ids.size() > 0 && ids.size() != count) {
|
||||
throw new InvalidDataAccessApiUsageException("Inconsistent set of id values provided " +
|
||||
Arrays.asList((Object[]) dbo.get("$in")));
|
||||
throw new InvalidDataAccessApiUsageException("Inconsistent set of id values provided "
|
||||
+ Arrays.asList((Object[]) dbo.get("$in")));
|
||||
}
|
||||
if (ids.size() > 0) {
|
||||
dbo.removeField("$in");
|
||||
@@ -1162,12 +1187,14 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
private String determineCollectionName(Class<?> clazz) {
|
||||
|
||||
if (clazz == null) {
|
||||
throw new InvalidDataAccessApiUsageException("No class parameter provided, entity collection can't be determined for " + clazz);
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"No class parameter provided, entity collection can't be determined for " + clazz);
|
||||
}
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(clazz);
|
||||
if (entity == null) {
|
||||
throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class " + clazz.getName());
|
||||
throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class "
|
||||
+ clazz.getName());
|
||||
}
|
||||
return entity.getCollection();
|
||||
}
|
||||
@@ -1175,8 +1202,8 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
/**
|
||||
* Checks and handles any errors.
|
||||
* <p/>
|
||||
* TODO: current implementation logs errors - will be configurable to log warning, errors or
|
||||
* throw exception in later versions
|
||||
* TODO: current implementation logs errors - will be configurable to log warning, errors or throw exception in later
|
||||
* versions
|
||||
*/
|
||||
private void handleAnyWriteResultErrors(WriteResult wr, DBObject query, String operation) {
|
||||
if (WriteResultChecking.NONE == this.writeResultChecking) {
|
||||
@@ -1185,16 +1212,16 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
String error = wr.getError();
|
||||
int n = wr.getN();
|
||||
if (error != null) {
|
||||
String message = "Execution of '" + operation +
|
||||
(query == null ? "" : "' using '" + query.toString() + "' query") + " failed: " + error;
|
||||
String message = "Execution of '" + operation + (query == null ? "" : "' using '" + query.toString() + "' query")
|
||||
+ " failed: " + error;
|
||||
if (WriteResultChecking.EXCEPTION == this.writeResultChecking) {
|
||||
throw new DataIntegrityViolationException(message);
|
||||
} else {
|
||||
LOGGER.error(message);
|
||||
}
|
||||
} else if (n == 0) {
|
||||
String message = "Execution of '" + operation +
|
||||
(query == null ? "" : "' using '" + query.toString() + "' query") + " did not succeed: 0 documents updated";
|
||||
String message = "Execution of '" + operation + (query == null ? "" : "' using '" + query.toString() + "' query")
|
||||
+ " did not succeed: 0 documents updated";
|
||||
if (WriteResultChecking.EXCEPTION == this.writeResultChecking) {
|
||||
throw new DataIntegrityViolationException(message);
|
||||
} else {
|
||||
@@ -1207,7 +1234,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
/**
|
||||
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
|
||||
* exception if the conversation failed. Thus allows safe rethrowing of the return value.
|
||||
*
|
||||
*
|
||||
* @param ex
|
||||
* @return
|
||||
*/
|
||||
@@ -1221,11 +1248,10 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
converter.setDefaultDatabase(databaseName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification
|
||||
* {@link DBObject} and executes that against the {@link DBCollection}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
@@ -1248,7 +1274,8 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
return collection.findOne(query);
|
||||
} else {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("findOne using query: " + query + " fields: " + fields + " in db.collection: " + collection.getFullName());
|
||||
LOGGER.debug("findOne using query: " + query + " fields: " + fields + " in db.collection: "
|
||||
+ collection.getFullName());
|
||||
}
|
||||
return collection.findOne(query, fields);
|
||||
}
|
||||
@@ -1258,7 +1285,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
/**
|
||||
* Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification
|
||||
* {@link DBObject} and executes that against the {@link DBCollection}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
@@ -1289,7 +1316,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
/**
|
||||
* Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification
|
||||
* {@link DBObject} and executes that against the {@link DBCollection}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
private static class FindAndRemoveCallback implements CollectionCallback<DBObject> {
|
||||
@@ -1313,7 +1340,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
|
||||
/**
|
||||
* Simple internal callback to allow operations on a {@link DBObject}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
|
||||
@@ -1325,7 +1352,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher
|
||||
/**
|
||||
* Simple {@link DbObjectCallback} that will transform {@link DBObject} into the given target type using the given
|
||||
* {@link MongoReader}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class ReadDbObjectCallback<T> implements DbObjectCallback<T> {
|
||||
|
||||
@@ -19,19 +19,22 @@ import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* A MongoWriter is responsible for converting an object of type T to the native MongoDB representation DBObject.
|
||||
*
|
||||
* @param <T> the type of the object to convert to a DBObject
|
||||
*
|
||||
* @param <T>
|
||||
* the type of the object to convert to a DBObject
|
||||
* @author Mark Pollack
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
public interface MongoWriter<T> {
|
||||
|
||||
/**
|
||||
* Write the given object of type T to the native MongoDB object representation DBObject.
|
||||
*
|
||||
* @param t The object to convert to a DBObject
|
||||
* @param dbo The DBObject to use for writing.
|
||||
*/
|
||||
void write(T t, DBObject dbo);
|
||||
/**
|
||||
* Write the given object of type T to the native MongoDB object representation DBObject.
|
||||
*
|
||||
* @param t
|
||||
* The object to convert to a DBObject
|
||||
* @param dbo
|
||||
* The DBObject to use for writing.
|
||||
*/
|
||||
void write(T t, DBObject dbo);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
public enum WriteResultChecking {
|
||||
NONE, LOG, EXCEPTION
|
||||
NONE, LOG, EXCEPTION
|
||||
}
|
||||
|
||||
@@ -38,61 +38,63 @@ import com.mongodb.Mongo;
|
||||
@Configuration
|
||||
public abstract class AbstractMongoConfiguration {
|
||||
|
||||
@Bean
|
||||
public abstract Mongo mongo() throws Exception;
|
||||
|
||||
@Bean
|
||||
public abstract Mongo mongo() throws Exception;
|
||||
|
||||
@Bean
|
||||
public abstract MongoTemplate mongoTemplate() throws Exception;
|
||||
|
||||
public String getMappingBasePackage() {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public MongoMappingContext mongoMappingContext() throws ClassNotFoundException, LinkageError {
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
String basePackage = getMappingBasePackage();
|
||||
if (StringUtils.hasText(basePackage)) {
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||
|
||||
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
|
||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||
initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(), mappingContext.getClass().getClassLoader()));
|
||||
}
|
||||
mappingContext.setInitialEntitySet(initialEntitySet);
|
||||
}
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MappingMongoConverter mappingMongoConverter() throws Exception {
|
||||
MappingMongoConverter converter = new MappingMongoConverter(mongoMappingContext());
|
||||
converter.setMongo(mongo());
|
||||
afterMappingMongoConverterCreation(converter);
|
||||
return converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that allows post-processing after the MappingMongoConverter has been
|
||||
* successfully created.
|
||||
* @param converter
|
||||
*/
|
||||
protected void afterMappingMongoConverterCreation(MappingMongoConverter converter) {
|
||||
}
|
||||
@Bean
|
||||
public abstract MongoTemplate mongoTemplate() throws Exception;
|
||||
|
||||
@Bean
|
||||
public MappingContextAwareBeanPostProcessor mappingContextAwareBeanPostProcessor() {
|
||||
MappingContextAwareBeanPostProcessor bpp = new MappingContextAwareBeanPostProcessor();
|
||||
bpp.setMappingContextBeanName("mongoMappingContext");
|
||||
return bpp;
|
||||
}
|
||||
|
||||
@Bean MongoPersistentEntityIndexCreator mongoPersistentEntityIndexCreator() throws Exception {
|
||||
MongoPersistentEntityIndexCreator indexCreator = new MongoPersistentEntityIndexCreator(mongoMappingContext(), mongoTemplate() );
|
||||
return indexCreator;
|
||||
}
|
||||
public String getMappingBasePackage() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MongoMappingContext mongoMappingContext() throws ClassNotFoundException, LinkageError {
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
String basePackage = getMappingBasePackage();
|
||||
if (StringUtils.hasText(basePackage)) {
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
|
||||
false);
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||
|
||||
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
|
||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||
initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(), mappingContext.getClass()
|
||||
.getClassLoader()));
|
||||
}
|
||||
mappingContext.setInitialEntitySet(initialEntitySet);
|
||||
}
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MappingMongoConverter mappingMongoConverter() throws Exception {
|
||||
MappingMongoConverter converter = new MappingMongoConverter(mongoMappingContext());
|
||||
converter.setMongo(mongo());
|
||||
afterMappingMongoConverterCreation(converter);
|
||||
return converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that allows post-processing after the MappingMongoConverter has been successfully created.
|
||||
*
|
||||
* @param converter
|
||||
*/
|
||||
protected void afterMappingMongoConverterCreation(MappingMongoConverter converter) {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MappingContextAwareBeanPostProcessor mappingContextAwareBeanPostProcessor() {
|
||||
MappingContextAwareBeanPostProcessor bpp = new MappingContextAwareBeanPostProcessor();
|
||||
bpp.setMappingContextBeanName("mongoMappingContext");
|
||||
return bpp;
|
||||
}
|
||||
|
||||
@Bean
|
||||
MongoPersistentEntityIndexCreator mongoPersistentEntityIndexCreator() throws Exception {
|
||||
MongoPersistentEntityIndexCreator indexCreator = new MongoPersistentEntityIndexCreator(mongoMappingContext(),
|
||||
mongoTemplate());
|
||||
return indexCreator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
private static final String BASE_PACKAGE = "base-package";
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : "mappingConverter";
|
||||
}
|
||||
@@ -74,7 +75,8 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
String ctxRef = element.getAttribute("mapping-context-ref");
|
||||
if (!StringUtils.hasText(ctxRef)) {
|
||||
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContext.class);
|
||||
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MongoMappingContext.class);
|
||||
|
||||
Set<String> classesToAdd = getInititalEntityClasses(element, mappingContextBuilder);
|
||||
if (classesToAdd != null) {
|
||||
@@ -88,7 +90,8 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
try {
|
||||
registry.getBeanDefinition(POST_PROCESSOR);
|
||||
} catch (NoSuchBeanDefinitionException ignored) {
|
||||
BeanDefinitionBuilder postProcBuilder = BeanDefinitionBuilder.genericBeanDefinition(MappingContextAwareBeanPostProcessor.class);
|
||||
BeanDefinitionBuilder postProcBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MappingContextAwareBeanPostProcessor.class);
|
||||
postProcBuilder.addPropertyValue("mappingContextBeanName", ctxRef);
|
||||
registry.registerBeanDefinition(POST_PROCESSOR, postProcBuilder.getBeanDefinition());
|
||||
}
|
||||
@@ -104,9 +107,11 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
registry.getBeanDefinition(INDEX_HELPER);
|
||||
} catch (NoSuchBeanDefinitionException ignored) {
|
||||
String templateRef = element.getAttribute("mongo-template-ref");
|
||||
BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
|
||||
BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
|
||||
indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef));
|
||||
indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(StringUtils.hasText(templateRef) ? templateRef : TEMPLATE));
|
||||
indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(StringUtils.hasText(templateRef) ? templateRef
|
||||
: TEMPLATE));
|
||||
registry.registerBeanDefinition(INDEX_HELPER, indexHelperBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
@@ -126,7 +131,6 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
return converterBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getInititalEntityClasses(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
String basePackage = element.getAttribute(BASE_PACKAGE);
|
||||
@@ -135,7 +139,8 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
|
||||
false);
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||
|
||||
@@ -148,8 +153,8 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
}
|
||||
|
||||
public BeanMetadataElement parseConverter(Element element, ParserContext parserContext) {
|
||||
|
||||
String converterRef= element.getAttribute("ref");
|
||||
|
||||
String converterRef = element.getAttribute("ref");
|
||||
if (StringUtils.hasText(converterRef)) {
|
||||
return new RuntimeBeanReference(converterRef);
|
||||
}
|
||||
|
||||
@@ -28,42 +28,42 @@ import org.w3c.dom.Element;
|
||||
|
||||
public class MongoJmxParser implements BeanDefinitionParser {
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
String name = element.getAttribute("mongo-ref");
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = "mongo";
|
||||
}
|
||||
registerJmxComponents(name, element, parserContext);
|
||||
return null;
|
||||
}
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
String name = element.getAttribute("mongo-ref");
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = "mongo";
|
||||
}
|
||||
registerJmxComponents(name, element, parserContext);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void registerJmxComponents(String mongoRefName, Element element, ParserContext parserContext) {
|
||||
Object eleSource = parserContext.extractSource(element);
|
||||
protected void registerJmxComponents(String mongoRefName, Element element, ParserContext parserContext) {
|
||||
Object eleSource = parserContext.extractSource(element);
|
||||
|
||||
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
|
||||
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
|
||||
|
||||
createBeanDefEntry(AssertMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(BackgroundFlushingMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(BtreeIndexCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(ConnectionMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(GlobalLockMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(MemoryMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(OperationCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(ServerInfo.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(MongoAdmin.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(AssertMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(BackgroundFlushingMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(BtreeIndexCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(ConnectionMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(GlobalLockMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(MemoryMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(OperationCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(ServerInfo.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(MongoAdmin.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
|
||||
parserContext.registerComponent(compositeDef);
|
||||
|
||||
parserContext.registerComponent(compositeDef);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void createBeanDefEntry(Class<?> clazz, CompositeComponentDefinition compositeDef, String mongoRefName, Object eleSource, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
|
||||
builder.getRawBeanDefinition().setSource(eleSource);
|
||||
builder.addConstructorArgReference(mongoRefName);
|
||||
BeanDefinition assertDef = builder.getBeanDefinition();
|
||||
String assertName = parserContext.getReaderContext().registerWithGeneratedName(assertDef);
|
||||
compositeDef.addNestedComponent(new BeanComponentDefinition(assertDef, assertName));
|
||||
}
|
||||
protected void createBeanDefEntry(Class<?> clazz, CompositeComponentDefinition compositeDef, String mongoRefName,
|
||||
Object eleSource, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
|
||||
builder.getRawBeanDefinition().setSource(eleSource);
|
||||
builder.addConstructorArgReference(mongoRefName);
|
||||
BeanDefinition assertDef = builder.getBeanDefinition();
|
||||
String assertName = parserContext.getReaderContext().registerWithGeneratedName(assertDef);
|
||||
compositeDef.addNestedComponent(new BeanComponentDefinition(assertDef, assertName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,67 +28,68 @@ import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <mongo;gt; definitions. If no name
|
||||
*
|
||||
* Parser for <mongo;gt; definitions. If no name
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
public class MongoParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return MongoFactoryBean.class;
|
||||
}
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return MongoFactoryBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, builder);
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, builder);
|
||||
|
||||
setPropertyValue(element, builder, "port", "port");
|
||||
setPropertyValue(element, builder, "host", "host");
|
||||
setPropertyValue(element, builder, "port", "port");
|
||||
setPropertyValue(element, builder, "host", "host");
|
||||
|
||||
parseOptions(parserContext, element, builder);
|
||||
parseOptions(parserContext, element, builder);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the options sub-element. Populates the given attribute factory with the proper attributes.
|
||||
*
|
||||
* @param element
|
||||
* @param attrBuilder
|
||||
* @return true if parsing actually occured, false otherwise
|
||||
*/
|
||||
private boolean parseOptions(ParserContext parserContext, Element element,
|
||||
BeanDefinitionBuilder mongoBuilder) {
|
||||
Element optionsElement = DomUtils.getChildElementByTagName(element, "options");
|
||||
if (optionsElement == null)
|
||||
return false;
|
||||
/**
|
||||
* Parses the options sub-element. Populates the given attribute factory with the proper attributes.
|
||||
*
|
||||
* @param element
|
||||
* @param attrBuilder
|
||||
* @return true if parsing actually occured, false otherwise
|
||||
*/
|
||||
private boolean parseOptions(ParserContext parserContext, Element element, BeanDefinitionBuilder mongoBuilder) {
|
||||
Element optionsElement = DomUtils.getChildElementByTagName(element, "options");
|
||||
if (optionsElement == null)
|
||||
return false;
|
||||
|
||||
BeanDefinitionBuilder optionsDefBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoOptionsFactoryBean.class);
|
||||
BeanDefinitionBuilder optionsDefBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MongoOptionsFactoryBean.class);
|
||||
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "connectionsPerHost", "connectionsPerHost");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "threadsAllowedToBlockForConnectionMultiplier", "threadsAllowedToBlockForConnectionMultiplier");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "maxWaitTime", "maxWaitTime");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "connectTimeout", "connectTimeout");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "socketTimeout", "socketTimeout");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "autoConnectRetry", "autoConnectRetry");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "connectionsPerHost", "connectionsPerHost");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "threadsAllowedToBlockForConnectionMultiplier",
|
||||
"threadsAllowedToBlockForConnectionMultiplier");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "maxWaitTime", "maxWaitTime");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "connectTimeout", "connectTimeout");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "socketTimeout", "socketTimeout");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "autoConnectRetry", "autoConnectRetry");
|
||||
|
||||
mongoBuilder.addPropertyValue("mongoOptions", optionsDefBuilder.getBeanDefinition());
|
||||
return true;
|
||||
}
|
||||
mongoBuilder.addPropertyValue("mongoOptions", optionsDefBuilder.getBeanDefinition());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
String name = super.resolveId(element, definition, parserContext);
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = "mongo";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
String name = super.resolveId(element, definition, parserContext);
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = "mongo";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attrName, String propertyName) {
|
||||
String attr = element.getAttribute(attrName);
|
||||
if (StringUtils.hasText(attr)) {
|
||||
builder.addPropertyValue(propertyName, attr);
|
||||
}
|
||||
}
|
||||
private void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attrName, String propertyName) {
|
||||
String attr = element.getAttribute(attrName);
|
||||
if (StringUtils.hasText(attr)) {
|
||||
builder.addPropertyValue(propertyName, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,73 +23,68 @@ import org.springframework.data.mapping.model.MappingContext;
|
||||
import org.springframework.data.repository.config.AbstractRepositoryConfigDefinitionParser;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} to create
|
||||
* Mongo DB repositories from classpath scanning or manual definition.
|
||||
*
|
||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} to create Mongo DB repositories from classpath
|
||||
* scanning or manual definition.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoRepositoryConfigParser
|
||||
extends
|
||||
AbstractRepositoryConfigDefinitionParser<SimpleMongoRepositoryConfiguration, MongoRepositoryConfiguration> {
|
||||
|
||||
private static final String MAPPING_CONTEXT_DEFAULT = MappingMongoConverterParser.MAPPING_CONTEXT;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.config.
|
||||
* AbstractRepositoryConfigDefinitionParser
|
||||
* #getGlobalRepositoryConfigInformation(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected SimpleMongoRepositoryConfiguration getGlobalRepositoryConfigInformation(
|
||||
Element element) {
|
||||
public class MongoRepositoryConfigParser extends
|
||||
AbstractRepositoryConfigDefinitionParser<SimpleMongoRepositoryConfiguration, MongoRepositoryConfiguration> {
|
||||
|
||||
return new SimpleMongoRepositoryConfiguration(element);
|
||||
}
|
||||
private static final String MAPPING_CONTEXT_DEFAULT = MappingMongoConverterParser.MAPPING_CONTEXT;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.config.
|
||||
* AbstractRepositoryConfigDefinitionParser
|
||||
* #getGlobalRepositoryConfigInformation(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected SimpleMongoRepositoryConfiguration getGlobalRepositoryConfigInformation(Element element) {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.AbstractRepositoryConfigDefinitionParser#postProcessBeanDefinition(org.springframework.data.repository.config.SingleRepositoryConfigInformation, org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected void postProcessBeanDefinition(
|
||||
MongoRepositoryConfiguration context,
|
||||
BeanDefinitionBuilder builder, BeanDefinitionRegistry registry, Object beanSource) {
|
||||
return new SimpleMongoRepositoryConfiguration(element);
|
||||
}
|
||||
|
||||
builder.addPropertyReference("template", context.getMongoTemplateRef());
|
||||
|
||||
String mappingContextRef = getMappingContextReference(context, registry);
|
||||
if (mappingContextRef != null) {
|
||||
builder.addPropertyReference("mappingContext", mappingContextRef);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.AbstractRepositoryConfigDefinitionParser#postProcessBeanDefinition(org.springframework.data.repository.config.SingleRepositoryConfigInformation, org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected void postProcessBeanDefinition(MongoRepositoryConfiguration context, BeanDefinitionBuilder builder,
|
||||
BeanDefinitionRegistry registry, Object beanSource) {
|
||||
|
||||
/**
|
||||
* Returns the bean name of a {@link MappingContext} to be wired. Will inspect the namespace attribute first and if no
|
||||
* config is found in that place it will try to lookup the default one. Will return {@literal null} if neither one is
|
||||
* available.
|
||||
*
|
||||
* @param config
|
||||
* @param registry
|
||||
* @return
|
||||
*/
|
||||
private String getMappingContextReference(MongoRepositoryConfiguration config, BeanDefinitionRegistry registry) {
|
||||
|
||||
String contextRef = config.getMappingContextRef();
|
||||
|
||||
if (contextRef != null) {
|
||||
return contextRef;
|
||||
}
|
||||
|
||||
try {
|
||||
registry.getBeanDefinition(MAPPING_CONTEXT_DEFAULT);
|
||||
return MAPPING_CONTEXT_DEFAULT;
|
||||
} catch(NoSuchBeanDefinitionException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
builder.addPropertyReference("template", context.getMongoTemplateRef());
|
||||
|
||||
String mappingContextRef = getMappingContextReference(context, registry);
|
||||
if (mappingContextRef != null) {
|
||||
builder.addPropertyReference("mappingContext", mappingContextRef);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bean name of a {@link MappingContext} to be wired. Will inspect the namespace attribute first and if no
|
||||
* config is found in that place it will try to lookup the default one. Will return {@literal null} if neither one is
|
||||
* available.
|
||||
*
|
||||
* @param config
|
||||
* @param registry
|
||||
* @return
|
||||
*/
|
||||
private String getMappingContextReference(MongoRepositoryConfiguration config, BeanDefinitionRegistry registry) {
|
||||
|
||||
String contextRef = config.getMappingContextRef();
|
||||
|
||||
if (contextRef != null) {
|
||||
return contextRef;
|
||||
}
|
||||
|
||||
try {
|
||||
registry.getBeanDefinition(MAPPING_CONTEXT_DEFAULT);
|
||||
return MAPPING_CONTEXT_DEFAULT;
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,25 +17,23 @@ package org.springframework.data.document.mongodb.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB
|
||||
* based repositories.
|
||||
*
|
||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB based repositories.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoRepositoryNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||
*/
|
||||
public void init() {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||
*/
|
||||
public void init() {
|
||||
|
||||
registerBeanDefinitionParser("repositories", new MongoRepositoryConfigParser());
|
||||
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
|
||||
registerBeanDefinitionParser("mongo", new MongoParser());
|
||||
registerBeanDefinitionParser("jmx", new MongoJmxParser());
|
||||
}
|
||||
registerBeanDefinitionParser("repositories", new MongoRepositoryConfigParser());
|
||||
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
|
||||
registerBeanDefinitionParser("mongo", new MongoParser());
|
||||
registerBeanDefinitionParser("jmx", new MongoJmxParser());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,180 +23,160 @@ import org.springframework.data.repository.config.SingleRepositoryConfigInformat
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
|
||||
/**
|
||||
* {@link RepositoryConfig} implementation to create
|
||||
* {@link MongoRepositoryConfiguration} instances for both automatic and manual
|
||||
* configuration.
|
||||
*
|
||||
* {@link RepositoryConfig} implementation to create {@link MongoRepositoryConfiguration} instances for both automatic
|
||||
* and manual configuration.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SimpleMongoRepositoryConfiguration extends RepositoryConfig<SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration, SimpleMongoRepositoryConfiguration> {
|
||||
public class SimpleMongoRepositoryConfiguration
|
||||
extends
|
||||
RepositoryConfig<SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration, SimpleMongoRepositoryConfiguration> {
|
||||
|
||||
private static final String MONGO_TEMPLATE_REF = "mongo-template-ref";
|
||||
private static final String DEFAULT_MONGO_TEMPLATE_REF = "mongoTemplate";
|
||||
|
||||
private static final String MAPPING_CONTEXT_REF = "mongo-mapping-context-ref";
|
||||
private static final String MONGO_TEMPLATE_REF = "mongo-template-ref";
|
||||
private static final String DEFAULT_MONGO_TEMPLATE_REF = "mongoTemplate";
|
||||
|
||||
private static final String MAPPING_CONTEXT_REF = "mongo-mapping-context-ref";
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleMongoRepositoryConfiguration} for the given
|
||||
* {@link Element}.
|
||||
*
|
||||
* @param repositoriesElement
|
||||
*/
|
||||
protected SimpleMongoRepositoryConfiguration(Element repositoriesElement) {
|
||||
/**
|
||||
* Creates a new {@link SimpleMongoRepositoryConfiguration} for the given {@link Element}.
|
||||
*
|
||||
* @param repositoriesElement
|
||||
*/
|
||||
protected SimpleMongoRepositoryConfiguration(Element repositoriesElement) {
|
||||
|
||||
super(repositoriesElement, MongoRepositoryFactoryBean.class.getName());
|
||||
}
|
||||
super(repositoriesElement, MongoRepositoryFactoryBean.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bean name of the {@link org.springframework.data.document.mongodb.MongoTemplate} to be referenced.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getMongoTemplateRef() {
|
||||
|
||||
/**
|
||||
* Returns the bean name of the {@link org.springframework.data.document.mongodb.MongoTemplate} to be referenced.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getMongoTemplateRef() {
|
||||
String templateRef = getSource().getAttribute(MONGO_TEMPLATE_REF);
|
||||
return StringUtils.hasText(templateRef) ? templateRef : DEFAULT_MONGO_TEMPLATE_REF;
|
||||
}
|
||||
|
||||
String templateRef = getSource().getAttribute(MONGO_TEMPLATE_REF);
|
||||
return StringUtils.hasText(templateRef) ? templateRef
|
||||
: DEFAULT_MONGO_TEMPLATE_REF;
|
||||
}
|
||||
|
||||
public String getMappingContextRef() {
|
||||
|
||||
String attribute = getSource().getAttribute(MAPPING_CONTEXT_REF);
|
||||
return StringUtils.hasText(attribute) ? attribute : null;
|
||||
}
|
||||
public String getMappingContextRef() {
|
||||
|
||||
String attribute = getSource().getAttribute(MAPPING_CONTEXT_REF);
|
||||
return StringUtils.hasText(attribute) ? attribute : null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.config.GlobalRepositoryConfigInformation
|
||||
* #getAutoconfigRepositoryInformation(java.lang.String)
|
||||
*/
|
||||
public MongoRepositoryConfiguration getAutoconfigRepositoryInformation(
|
||||
String interfaceName) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.config.GlobalRepositoryConfigInformation
|
||||
* #getAutoconfigRepositoryInformation(java.lang.String)
|
||||
*/
|
||||
public MongoRepositoryConfiguration getAutoconfigRepositoryInformation(String interfaceName) {
|
||||
|
||||
return new AutomaticMongoRepositoryConfiguration(interfaceName, this);
|
||||
}
|
||||
return new AutomaticMongoRepositoryConfiguration(interfaceName, this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.config.RepositoryConfig#
|
||||
* createSingleRepositoryConfigInformationFor(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected MongoRepositoryConfiguration createSingleRepositoryConfigInformationFor(Element element) {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.config.RepositoryConfig#
|
||||
* createSingleRepositoryConfigInformationFor(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected MongoRepositoryConfiguration createSingleRepositoryConfigInformationFor(
|
||||
Element element) {
|
||||
return new ManualMongoRepositoryConfiguration(element, this);
|
||||
}
|
||||
|
||||
return new ManualMongoRepositoryConfiguration(element, this);
|
||||
}
|
||||
/**
|
||||
* Simple interface for configuration values specific to Mongo repositories.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoRepositoryConfiguration extends
|
||||
SingleRepositoryConfigInformation<SimpleMongoRepositoryConfiguration> {
|
||||
|
||||
/**
|
||||
* Simple interface for configuration values specific to Mongo repositories.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoRepositoryConfiguration
|
||||
extends
|
||||
SingleRepositoryConfigInformation<SimpleMongoRepositoryConfiguration> {
|
||||
String getMongoTemplateRef();
|
||||
|
||||
String getMongoTemplateRef();
|
||||
|
||||
String getMappingContextRef();
|
||||
}
|
||||
String getMappingContextRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements manual lookup of the additional attributes.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class ManualMongoRepositoryConfiguration
|
||||
extends
|
||||
ManualRepositoryConfigInformation<SimpleMongoRepositoryConfiguration>
|
||||
implements MongoRepositoryConfiguration {
|
||||
/**
|
||||
* Implements manual lookup of the additional attributes.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class ManualMongoRepositoryConfiguration extends
|
||||
ManualRepositoryConfigInformation<SimpleMongoRepositoryConfiguration> implements MongoRepositoryConfiguration {
|
||||
|
||||
/**
|
||||
* Creates a new {@link ManualMongoRepositoryConfiguration} for the
|
||||
* given {@link Element} and parent.
|
||||
*
|
||||
* @param element
|
||||
* @param parent
|
||||
*/
|
||||
public ManualMongoRepositoryConfiguration(Element element,
|
||||
SimpleMongoRepositoryConfiguration parent) {
|
||||
/**
|
||||
* Creates a new {@link ManualMongoRepositoryConfiguration} for the given {@link Element} and parent.
|
||||
*
|
||||
* @param element
|
||||
* @param parent
|
||||
*/
|
||||
public ManualMongoRepositoryConfiguration(Element element, SimpleMongoRepositoryConfiguration parent) {
|
||||
|
||||
super(element, parent);
|
||||
}
|
||||
super(element, parent);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.config.
|
||||
* SimpleMongoRepositoryConfiguration
|
||||
* .MongoRepositoryConfiguration#getMongoTemplateRef()
|
||||
*/
|
||||
public String getMongoTemplateRef() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.config.
|
||||
* SimpleMongoRepositoryConfiguration
|
||||
* .MongoRepositoryConfiguration#getMongoTemplateRef()
|
||||
*/
|
||||
public String getMongoTemplateRef() {
|
||||
return getAttribute(MONGO_TEMPLATE_REF);
|
||||
}
|
||||
|
||||
return getAttribute(MONGO_TEMPLATE_REF);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getMappingContextRef()
|
||||
*/
|
||||
public String getMappingContextRef() {
|
||||
return getAttribute(MAPPING_CONTEXT_REF);
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getMappingContextRef()
|
||||
*/
|
||||
public String getMappingContextRef() {
|
||||
return getAttribute(MAPPING_CONTEXT_REF);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the lookup of the additional attributes during automatic
|
||||
* configuration.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class AutomaticMongoRepositoryConfiguration
|
||||
extends
|
||||
AutomaticRepositoryConfigInformation<SimpleMongoRepositoryConfiguration>
|
||||
implements MongoRepositoryConfiguration {
|
||||
/**
|
||||
* Implements the lookup of the additional attributes during automatic configuration.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class AutomaticMongoRepositoryConfiguration extends
|
||||
AutomaticRepositoryConfigInformation<SimpleMongoRepositoryConfiguration> implements MongoRepositoryConfiguration {
|
||||
|
||||
/**
|
||||
* Creates a new {@link AutomaticMongoRepositoryConfiguration} for the
|
||||
* given interface and parent.
|
||||
*
|
||||
* @param interfaceName
|
||||
* @param parent
|
||||
*/
|
||||
public AutomaticMongoRepositoryConfiguration(String interfaceName,
|
||||
SimpleMongoRepositoryConfiguration parent) {
|
||||
/**
|
||||
* Creates a new {@link AutomaticMongoRepositoryConfiguration} for the given interface and parent.
|
||||
*
|
||||
* @param interfaceName
|
||||
* @param parent
|
||||
*/
|
||||
public AutomaticMongoRepositoryConfiguration(String interfaceName, SimpleMongoRepositoryConfiguration parent) {
|
||||
|
||||
super(interfaceName, parent);
|
||||
}
|
||||
super(interfaceName, parent);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.config.
|
||||
* SimpleMongoRepositoryConfiguration
|
||||
* .MongoRepositoryConfiguration#getMongoTemplateRef()
|
||||
*/
|
||||
public String getMongoTemplateRef() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.config.
|
||||
* SimpleMongoRepositoryConfiguration
|
||||
* .MongoRepositoryConfiguration#getMongoTemplateRef()
|
||||
*/
|
||||
public String getMongoTemplateRef() {
|
||||
return getParent().getMongoTemplateRef();
|
||||
}
|
||||
|
||||
return getParent().getMongoTemplateRef();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getMappingContextRef()
|
||||
*/
|
||||
public String getMappingContextRef() {
|
||||
return getParent().getMappingContextRef();
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getMappingContextRef()
|
||||
*/
|
||||
public String getMappingContextRef() {
|
||||
return getParent().getMappingContextRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
* Spring XML namespace configuration for MongoDB specific repositories.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb.config;
|
||||
|
||||
|
||||
@@ -72,19 +72,22 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
/**
|
||||
* {@link MongoConverter} that uses a {@link MappingContext} to do sophisticated mapping of domain objects to
|
||||
* {@link DBObject}.
|
||||
*
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware, InitializingBean {
|
||||
|
||||
public static final String CUSTOM_TYPE_KEY = "_class";
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private static final List<Class<?>> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class, DBObject.class);
|
||||
private static final List<Class<?>> VALID_ID_TYPES = Arrays.asList(new Class<?>[]{ObjectId.class, String.class, BigInteger.class, byte[].class});
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
private static final List<Class<?>> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class,
|
||||
DBObject.class);
|
||||
private static final List<Class<?>> VALID_ID_TYPES = Arrays.asList(new Class<?>[] { ObjectId.class, String.class,
|
||||
BigInteger.class, byte[].class });
|
||||
protected static final Log log = LogFactory.getLog(MappingMongoConverter.class);
|
||||
|
||||
protected final GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
protected final GenericConversionService conversionService = ConversionServiceFactory
|
||||
.createDefaultConversionService();
|
||||
protected final Set<ConvertiblePair> customTypeMapping = new HashSet<ConvertiblePair>();
|
||||
protected final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
protected SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
|
||||
@@ -95,10 +98,11 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingMongoConverter} with the given {@link MappingContext}.
|
||||
*
|
||||
*
|
||||
* @param mappingContext
|
||||
*/
|
||||
public MappingMongoConverter(MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
public MappingMongoConverter(
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
this.mappingContext = mappingContext;
|
||||
this.conversionService.removeConvertible(Object.class, String.class);
|
||||
}
|
||||
@@ -106,7 +110,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
/**
|
||||
* Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over
|
||||
* metadata driven conversion between of objects to/from DBObject
|
||||
*
|
||||
*
|
||||
* @param converters
|
||||
*/
|
||||
public void setConverters(List<Converter<?, ?>> converters) {
|
||||
@@ -120,7 +124,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
/**
|
||||
* Inspects the given {@link Converter} for the types it can convert and registers the pair for custom type conversion
|
||||
* in case the target type is a Mongo basic type.
|
||||
*
|
||||
*
|
||||
* @param converter
|
||||
*/
|
||||
private void registerConverter(Converter<?, ?> converter) {
|
||||
@@ -177,50 +181,51 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
public <S extends Object> S read(Class<S> clazz, final DBObject dbo) {
|
||||
return read(ClassTypeInformation.from(clazz), dbo);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <S extends Object> S read(TypeInformation<S> type, DBObject dbo) {
|
||||
|
||||
if (null == dbo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
TypeInformation<? extends S> typeToUse = getMoreConcreteTargetType(dbo, type);
|
||||
Class<? extends S> rawType = typeToUse.getType();
|
||||
Class<?> customTarget = getCustomTarget(rawType, DBObject.class);
|
||||
protected <S extends Object> S read(TypeInformation<S> type, DBObject dbo) {
|
||||
|
||||
if (customTarget != null) {
|
||||
return conversionService.convert(dbo, rawType);
|
||||
}
|
||||
if (null == dbo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeToUse.isCollectionLike() && dbo instanceof BasicDBList) {
|
||||
List<Object> l = new ArrayList<Object>();
|
||||
BasicDBList dbList = (BasicDBList) dbo;
|
||||
for (Object o : dbList) {
|
||||
if (o instanceof DBObject) {
|
||||
|
||||
Object newObj = read(typeToUse.getComponentType(), (DBObject) o);
|
||||
Class<?> rawComponentType = typeToUse.getComponentType().getType();
|
||||
|
||||
if (newObj.getClass().isAssignableFrom(rawComponentType)) {
|
||||
l.add(newObj);
|
||||
} else {
|
||||
l.add(conversionService.convert(newObj, rawComponentType));
|
||||
}
|
||||
} else {
|
||||
l.add(o);
|
||||
}
|
||||
}
|
||||
return conversionService.convert(l, rawType);
|
||||
}
|
||||
TypeInformation<? extends S> typeToUse = getMoreConcreteTargetType(dbo, type);
|
||||
Class<? extends S> rawType = typeToUse.getType();
|
||||
Class<?> customTarget = getCustomTarget(rawType, DBObject.class);
|
||||
|
||||
// Retrieve persistent entity info
|
||||
MongoPersistentEntity<S> persistentEntity = (MongoPersistentEntity<S>) mappingContext.getPersistentEntity(typeToUse);
|
||||
if (persistentEntity == null) {
|
||||
throw new MappingException("No mapping metadata found for " + rawType.getName());
|
||||
}
|
||||
if (customTarget != null) {
|
||||
return conversionService.convert(dbo, rawType);
|
||||
}
|
||||
|
||||
return read(persistentEntity, dbo);
|
||||
if (typeToUse.isCollectionLike() && dbo instanceof BasicDBList) {
|
||||
List<Object> l = new ArrayList<Object>();
|
||||
BasicDBList dbList = (BasicDBList) dbo;
|
||||
for (Object o : dbList) {
|
||||
if (o instanceof DBObject) {
|
||||
|
||||
Object newObj = read(typeToUse.getComponentType(), (DBObject) o);
|
||||
Class<?> rawComponentType = typeToUse.getComponentType().getType();
|
||||
|
||||
if (newObj.getClass().isAssignableFrom(rawComponentType)) {
|
||||
l.add(newObj);
|
||||
} else {
|
||||
l.add(conversionService.convert(newObj, rawComponentType));
|
||||
}
|
||||
} else {
|
||||
l.add(o);
|
||||
}
|
||||
}
|
||||
return conversionService.convert(l, rawType);
|
||||
}
|
||||
|
||||
// Retrieve persistent entity info
|
||||
MongoPersistentEntity<S> persistentEntity = (MongoPersistentEntity<S>) mappingContext
|
||||
.getPersistentEntity(typeToUse);
|
||||
if (persistentEntity == null) {
|
||||
throw new MappingException("No mapping metadata found for " + rawType.getName());
|
||||
}
|
||||
|
||||
return read(persistentEntity, dbo);
|
||||
}
|
||||
|
||||
private <S extends Object> S read(final MongoPersistentEntity<S> entity, final DBObject dbo) {
|
||||
@@ -230,7 +235,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
spelCtx.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
||||
}
|
||||
if (!(dbo instanceof BasicDBList)) {
|
||||
String[] keySet = dbo.keySet().toArray(new String[]{});
|
||||
String[] keySet = dbo.keySet().toArray(new String[] {});
|
||||
for (String key : keySet) {
|
||||
spelCtx.setVariable(key, dbo.get(key));
|
||||
}
|
||||
@@ -240,7 +245,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
final MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
final S instance = constructInstance(entity, new PreferredConstructor.ParameterValueProvider() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getParameterValue(PreferredConstructor.Parameter<T> parameter) {
|
||||
public <T> T getParameterValue(PreferredConstructor.Parameter<T> parameter) {
|
||||
String name = parameter.getName();
|
||||
TypeInformation<T> type = parameter.getType();
|
||||
Class<T> rawType = parameter.getRawType();
|
||||
@@ -269,17 +274,17 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
// Set properties not already set in the constructor
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
||||
|
||||
boolean isConstructorProperty = ctorParamNames.contains(prop.getName());
|
||||
boolean hasValueForProperty = dbo.containsField(prop.getKey());
|
||||
|
||||
|
||||
boolean isConstructorProperty = ctorParamNames.contains(prop.getName());
|
||||
boolean hasValueForProperty = dbo.containsField(prop.getKey());
|
||||
|
||||
if (!hasValueForProperty || isConstructorProperty) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object obj = getValueInternal(prop, dbo, spelCtx, prop.getSpelExpression());
|
||||
try {
|
||||
setProperty(instance, prop, obj, useFieldAccessOnly);
|
||||
setProperty(instance, prop, obj, useFieldAccessOnly);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
@@ -306,56 +311,56 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Root entry method into write conversion. Adds a type discriminator to the {@link DBObject}. Shouldn't be called for
|
||||
* nested conversions.
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.MongoWriter#write(java.lang.Object, com.mongodb.DBObject)
|
||||
*/
|
||||
public void write(final Object obj, final DBObject dbo) {
|
||||
|
||||
/**
|
||||
* Root entry method into write conversion. Adds a type discriminator to the {@link DBObject}. Shouldn't be called for
|
||||
* nested conversions.
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.MongoWriter#write(java.lang.Object, com.mongodb.DBObject)
|
||||
*/
|
||||
public void write(final Object obj, final DBObject dbo) {
|
||||
|
||||
if (null == obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean handledByCustomConverter = getCustomTarget(obj.getClass(), DBObject.class) != null;
|
||||
|
||||
|
||||
if (!handledByCustomConverter) {
|
||||
dbo.put(CUSTOM_TYPE_KEY, obj.getClass().getName());
|
||||
dbo.put(CUSTOM_TYPE_KEY, obj.getClass().getName());
|
||||
}
|
||||
|
||||
writeInternal(obj, dbo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal write conversion method which should be used for nested invocations.
|
||||
*
|
||||
* @param obj
|
||||
* @param dbo
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal write conversion method which should be used for nested invocations.
|
||||
*
|
||||
* @param obj
|
||||
* @param dbo
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void writeInternal(final Object obj, final DBObject dbo) {
|
||||
|
||||
if (null == obj) {
|
||||
return;
|
||||
}
|
||||
protected void writeInternal(final Object obj, final DBObject dbo) {
|
||||
|
||||
Class<?> customTarget = getCustomTarget(obj.getClass(), DBObject.class);
|
||||
if (null == obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (customTarget != null) {
|
||||
DBObject result = conversionService.convert(obj, DBObject.class);
|
||||
dbo.putAll(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Map.class.isAssignableFrom(obj.getClass())) {
|
||||
writeMapInternal((Map<Object, Object>) obj, dbo);
|
||||
return;
|
||||
}
|
||||
Class<?> customTarget = getCustomTarget(obj.getClass(), DBObject.class);
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(obj.getClass());
|
||||
writeInternal(obj, dbo, entity);
|
||||
}
|
||||
if (customTarget != null) {
|
||||
DBObject result = conversionService.convert(obj, DBObject.class);
|
||||
dbo.putAll(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Map.class.isAssignableFrom(obj.getClass())) {
|
||||
writeMapInternal((Map<Object, Object>) obj, dbo);
|
||||
return;
|
||||
}
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(obj.getClass());
|
||||
writeInternal(obj, dbo, entity);
|
||||
}
|
||||
|
||||
protected void writeInternal(final Object obj, final DBObject dbo, MongoPersistentEntity<?> entity) {
|
||||
|
||||
@@ -383,7 +388,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
dbo.put("_id", idObj);
|
||||
} else {
|
||||
if (!VALID_ID_TYPES.contains(idProperty.getType())) {
|
||||
throw new MappingException("Invalid data type " + idProperty.getType().getName() + " for Id property. Should be one of " + VALID_ID_TYPES);
|
||||
throw new MappingException("Invalid data type " + idProperty.getType().getName()
|
||||
+ " for Id property. Should be one of " + VALID_ID_TYPES);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -413,7 +419,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
entity.doWithAssociations(new AssociationHandler<MongoPersistentProperty>() {
|
||||
public void doWithAssociation(Association<MongoPersistentProperty> association) {
|
||||
MongoPersistentProperty inverseProp = association.getInverse();
|
||||
MongoPersistentProperty inverseProp = association.getInverse();
|
||||
Class<?> type = inverseProp.getType();
|
||||
Object propertyObj;
|
||||
try {
|
||||
@@ -456,10 +462,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
setConversionService(conversionService);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected void writePropertyInternal(MongoPersistentProperty prop, Object obj, DBObject dbo) {
|
||||
org.springframework.data.document.mongodb.mapping.DBRef dbref = prop.getField()
|
||||
.getAnnotation(org.springframework.data.document.mongodb.mapping.DBRef.class);
|
||||
org.springframework.data.document.mongodb.mapping.DBRef dbref = prop.getField().getAnnotation(
|
||||
org.springframework.data.document.mongodb.mapping.DBRef.class);
|
||||
|
||||
String name = prop.getName();
|
||||
Class<?> type = prop.getType();
|
||||
@@ -542,16 +548,15 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
Object key = entry.getKey();
|
||||
Object val = entry.getValue();
|
||||
if (isSimpleType(key.getClass())) {
|
||||
// Don't use conversion service here as removal of ObjectToString converter results in some primitive types not
|
||||
// being convertable
|
||||
// Don't use conversion service here as removal of ObjectToString converter results in some primitive types not
|
||||
// being convertable
|
||||
String simpleKey = key.toString();
|
||||
if (isSimpleType(val.getClass())) {
|
||||
dbo.put(simpleKey, val);
|
||||
} else {
|
||||
DBObject newDbo = new BasicDBObject();
|
||||
Class<?> componentType = val.getClass();
|
||||
if (componentType.isArray()
|
||||
|| componentType.isAssignableFrom(Collection.class)
|
||||
if (componentType.isArray() || componentType.isAssignableFrom(Collection.class)
|
||||
|| componentType.isAssignableFrom(List.class)) {
|
||||
Class<?> ctype = val.getClass().getComponentType();
|
||||
dbo.put("_class", (null != ctype ? ctype.getName() : componentType.getName()));
|
||||
@@ -600,15 +605,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return new DBRef(db, collection, id);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
protected Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, StandardEvaluationContext ctx, String spelExpr) {
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, StandardEvaluationContext ctx,
|
||||
String spelExpr) {
|
||||
|
||||
Object o;
|
||||
if (null != spelExpr) {
|
||||
Expression x = spelExpressionParser.parseExpression(spelExpr);
|
||||
o = x.getValue(ctx);
|
||||
} else {
|
||||
|
||||
|
||||
Object dbObj = dbo.get(prop.getKey());
|
||||
|
||||
if (dbObj == null) {
|
||||
@@ -636,10 +642,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
if (entry.getKey().equals(CUSTOM_TYPE_KEY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Class<?> keyType = prop.getComponentType();
|
||||
Object key = conversionService.convert(entry.getKey(), keyType);
|
||||
|
||||
|
||||
if (null != entry.getValue() && entry.getValue() instanceof DBObject) {
|
||||
m.put(key, read((null != toType ? toType : prop.getMapValueType()), (DBObject) entry.getValue()));
|
||||
} else {
|
||||
@@ -688,7 +694,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
/**
|
||||
* Returns the type to be used to convert the DBObject given to.
|
||||
*
|
||||
*
|
||||
* @param dbObject
|
||||
* @return
|
||||
*/
|
||||
@@ -706,21 +712,21 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the a custom class definition stored inside the given {@link DBObject} and returns that in case it's a
|
||||
* subtype of the given basic one.
|
||||
*
|
||||
* @param dbObject
|
||||
* @param basicType
|
||||
* @return
|
||||
*/
|
||||
/**
|
||||
* Inspects the a custom class definition stored inside the given {@link DBObject} and returns that in case it's a
|
||||
* subtype of the given basic one.
|
||||
*
|
||||
* @param dbObject
|
||||
* @param basicType
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <S> TypeInformation<? extends S> getMoreConcreteTargetType(DBObject dbObject, TypeInformation<S> basicType) {
|
||||
Class<?> documentsTargetType = findTypeToBeUsed(dbObject);
|
||||
Class<S> rawType = basicType.getType();
|
||||
boolean isMoreConcreteCustomType = documentsTargetType != null && rawType.isAssignableFrom(documentsTargetType);
|
||||
return isMoreConcreteCustomType ? (TypeInformation<? extends S>) ClassTypeInformation.from(documentsTargetType)
|
||||
: basicType;
|
||||
private <S> TypeInformation<? extends S> getMoreConcreteTargetType(DBObject dbObject, TypeInformation<S> basicType) {
|
||||
Class<?> documentsTargetType = findTypeToBeUsed(dbObject);
|
||||
Class<S> rawType = basicType.getType();
|
||||
boolean isMoreConcreteCustomType = documentsTargetType != null && rawType.isAssignableFrom(documentsTargetType);
|
||||
return isMoreConcreteCustomType ? (TypeInformation<? extends S>) ClassTypeInformation.from(documentsTargetType)
|
||||
: basicType;
|
||||
}
|
||||
|
||||
protected <T> List<?> unwrapList(BasicDBList dbList, TypeInformation<T> targetType) {
|
||||
|
||||
@@ -28,67 +28,67 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Custom Mongo specific {@link BeanWrapper} to allow access to bean properties via {@link MongoPropertyDescriptor}s.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class MongoBeanWrapper {
|
||||
|
||||
private final ConfigurablePropertyAccessor accessor;
|
||||
private final MongoPropertyDescriptors descriptors;
|
||||
private final boolean fieldAccess;
|
||||
private final ConfigurablePropertyAccessor accessor;
|
||||
private final MongoPropertyDescriptors descriptors;
|
||||
private final boolean fieldAccess;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoBeanWrapper} for the given target object and {@link ConversionService}.
|
||||
*
|
||||
* @param target
|
||||
* @param conversionService
|
||||
* @param fieldAccess
|
||||
*/
|
||||
public MongoBeanWrapper(Object target, ConversionService conversionService, boolean fieldAccess) {
|
||||
/**
|
||||
* Creates a new {@link MongoBeanWrapper} for the given target object and {@link ConversionService}.
|
||||
*
|
||||
* @param target
|
||||
* @param conversionService
|
||||
* @param fieldAccess
|
||||
*/
|
||||
public MongoBeanWrapper(Object target, ConversionService conversionService, boolean fieldAccess) {
|
||||
|
||||
Assert.notNull(target);
|
||||
Assert.notNull(conversionService);
|
||||
Assert.notNull(target);
|
||||
Assert.notNull(conversionService);
|
||||
|
||||
this.fieldAccess = fieldAccess;
|
||||
this.accessor = fieldAccess ? forDirectFieldAccess(target) : forBeanPropertyAccess(target);
|
||||
this.accessor.setConversionService(conversionService);
|
||||
this.descriptors = new MongoPropertyDescriptors(target.getClass());
|
||||
}
|
||||
this.fieldAccess = fieldAccess;
|
||||
this.accessor = fieldAccess ? forDirectFieldAccess(target) : forBeanPropertyAccess(target);
|
||||
this.accessor.setConversionService(conversionService);
|
||||
this.descriptors = new MongoPropertyDescriptors(target.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all {@link MongoPropertyDescriptors.MongoPropertyDescriptor}s for the underlying target object.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public MongoPropertyDescriptors getDescriptors() {
|
||||
return this.descriptors;
|
||||
}
|
||||
/**
|
||||
* Returns all {@link MongoPropertyDescriptors.MongoPropertyDescriptor}s for the underlying target object.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public MongoPropertyDescriptors getDescriptors() {
|
||||
return this.descriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the underlying object for the given property.
|
||||
*
|
||||
* @param descriptor
|
||||
* @return
|
||||
*/
|
||||
public Object getValue(MongoPropertyDescriptors.MongoPropertyDescriptor descriptor) {
|
||||
Assert.notNull(descriptor);
|
||||
return accessor.getPropertyValue(descriptor.getName());
|
||||
}
|
||||
/**
|
||||
* Returns the value of the underlying object for the given property.
|
||||
*
|
||||
* @param descriptor
|
||||
* @return
|
||||
*/
|
||||
public Object getValue(MongoPropertyDescriptors.MongoPropertyDescriptor descriptor) {
|
||||
Assert.notNull(descriptor);
|
||||
return accessor.getPropertyValue(descriptor.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the property of the underlying object to the given value.
|
||||
*
|
||||
* @param descriptor
|
||||
* @param value
|
||||
*/
|
||||
public void setValue(MongoPropertyDescriptors.MongoPropertyDescriptor descriptor, Object value) {
|
||||
Assert.notNull(descriptor);
|
||||
try {
|
||||
accessor.setPropertyValue(descriptor.getName(), value);
|
||||
} catch (NotWritablePropertyException e) {
|
||||
if (!fieldAccess) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sets the property of the underlying object to the given value.
|
||||
*
|
||||
* @param descriptor
|
||||
* @param value
|
||||
*/
|
||||
public void setValue(MongoPropertyDescriptors.MongoPropertyDescriptor descriptor, Object value) {
|
||||
Assert.notNull(descriptor);
|
||||
try {
|
||||
accessor.setPropertyValue(descriptor.getName(), value);
|
||||
} catch (NotWritablePropertyException e) {
|
||||
if (!fieldAccess) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,29 +23,30 @@ import org.springframework.data.document.mongodb.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.document.mongodb.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mapping.model.MappingContext;
|
||||
|
||||
|
||||
public interface MongoConverter extends MongoWriter<Object>, MongoReader<Object> {
|
||||
|
||||
/**
|
||||
* Converts the given {@link ObjectId} to the given target type.
|
||||
*
|
||||
* @param <T> the actual type to create
|
||||
* @param id the source {@link ObjectId}
|
||||
* @param targetType the target type to convert the {@link ObjectId} to
|
||||
* @return
|
||||
*/
|
||||
public <T> T convertObjectId(ObjectId id, Class<T> targetType);
|
||||
/**
|
||||
* Converts the given {@link ObjectId} to the given target type.
|
||||
*
|
||||
* @param <T>
|
||||
* the actual type to create
|
||||
* @param id
|
||||
* the source {@link ObjectId}
|
||||
* @param targetType
|
||||
* the target type to convert the {@link ObjectId} to
|
||||
* @return
|
||||
*/
|
||||
public <T> T convertObjectId(ObjectId id, Class<T> targetType);
|
||||
|
||||
/**
|
||||
* Returns the {@link ObjectId} instance for the given id.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public ObjectId convertObjectId(Object id);
|
||||
|
||||
/**
|
||||
* Returns the {@link ObjectId} instance for the given id.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public ObjectId convertObjectId(Object id);
|
||||
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getMappingContext();
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getMappingContext();
|
||||
|
||||
Object maybeConvertObject(Object obj);
|
||||
|
||||
|
||||
@@ -22,67 +22,67 @@ import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
/**
|
||||
* Wrapper class to contain useful {@link ObjectId}-to-something-and-back converters.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
abstract class ObjectIdConverters {
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private ObjectIdConverters() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple singleton to convert {@link ObjectId}s to their {@link String} representation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum ObjectIdToStringConverter implements Converter<ObjectId, String> {
|
||||
INSTANCE;
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private ObjectIdConverters() {
|
||||
|
||||
public String convert(ObjectId id) {
|
||||
return id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple singleton to convert {@link String}s to their {@link ObjectId} representation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum StringToObjectIdConverter implements Converter<String, ObjectId> {
|
||||
INSTANCE;
|
||||
}
|
||||
|
||||
public ObjectId convert(String source) {
|
||||
return new ObjectId(source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple singleton to convert {@link ObjectId}s to their {@link java.math.BigInteger} representation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum ObjectIdToBigIntegerConverter implements Converter<ObjectId, BigInteger> {
|
||||
INSTANCE;
|
||||
/**
|
||||
* Simple singleton to convert {@link ObjectId}s to their {@link String} representation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum ObjectIdToStringConverter implements Converter<ObjectId, String> {
|
||||
INSTANCE;
|
||||
|
||||
public BigInteger convert(ObjectId source) {
|
||||
return new BigInteger(source.toString(), 16);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple singleton to convert {@link BigInteger}s to their {@link ObjectId} representation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum BigIntegerToObjectIdConverter implements Converter<BigInteger, ObjectId> {
|
||||
INSTANCE;
|
||||
public String convert(ObjectId id) {
|
||||
return id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectId convert(BigInteger source) {
|
||||
return new ObjectId(source.toString(16));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Simple singleton to convert {@link String}s to their {@link ObjectId} representation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum StringToObjectIdConverter implements Converter<String, ObjectId> {
|
||||
INSTANCE;
|
||||
|
||||
public ObjectId convert(String source) {
|
||||
return new ObjectId(source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple singleton to convert {@link ObjectId}s to their {@link java.math.BigInteger} representation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum ObjectIdToBigIntegerConverter implements Converter<ObjectId, BigInteger> {
|
||||
INSTANCE;
|
||||
|
||||
public BigInteger convert(ObjectId source) {
|
||||
return new BigInteger(source.toString(), 16);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple singleton to convert {@link BigInteger}s to their {@link ObjectId} representation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum BigIntegerToObjectIdConverter implements Converter<BigInteger, ObjectId> {
|
||||
INSTANCE;
|
||||
|
||||
public ObjectId convert(BigInteger source) {
|
||||
return new ObjectId(source.toString(16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ import org.springframework.util.comparator.CompoundComparator;
|
||||
|
||||
/**
|
||||
* Basic {@link MongoConverter} implementation to convert between domain classes and {@link DBObject}s.
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
@@ -73,7 +73,8 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(SimpleMongoConverter.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final List<Class<?>> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class, DBObject.class);
|
||||
private static final List<Class<?>> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class,
|
||||
DBObject.class);
|
||||
private static final Set<String> SIMPLE_TYPES;
|
||||
|
||||
static {
|
||||
@@ -165,9 +166,9 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over
|
||||
* using object traversal to convert and object to/from DBObject
|
||||
*
|
||||
* Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over using
|
||||
* object traversal to convert and object to/from DBObject
|
||||
*
|
||||
* @param converters
|
||||
*/
|
||||
public void setConverters(Set<?> converters) {
|
||||
@@ -232,7 +233,7 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
|
||||
/**
|
||||
* Writes the given value to the given {@link DBObject}. Will skip {@literal null} values.
|
||||
*
|
||||
*
|
||||
* @param dbo
|
||||
* @param keyToUse
|
||||
* @param value
|
||||
@@ -248,7 +249,7 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
|
||||
/**
|
||||
* Writes the given {@link CompoundComparator} value to the given {@link DBObject}.
|
||||
*
|
||||
*
|
||||
* @param dbo
|
||||
* @param keyToUse
|
||||
* @param value
|
||||
@@ -284,7 +285,7 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
/**
|
||||
* Returns whether the {@link ConversionService} has a custom {@link Converter} registered that can convert the given
|
||||
* object into one of the types supported by MongoDB.
|
||||
*
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
@@ -300,7 +301,7 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
|
||||
/**
|
||||
* Writes the given {@link Map} to the given {@link DBObject}.
|
||||
*
|
||||
*
|
||||
* @param dbo
|
||||
* @param mapKey
|
||||
* @param map
|
||||
@@ -335,7 +336,7 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
|
||||
/**
|
||||
* Writes the given array to the given {@link DBObject}.
|
||||
*
|
||||
*
|
||||
* @param dbo
|
||||
* @param keyToUse
|
||||
* @param array
|
||||
@@ -381,24 +382,20 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
Object value = source.get(keyToUse);
|
||||
if (!isSimpleType(value.getClass())) {
|
||||
if (value instanceof Object[]) {
|
||||
bw.setValue(descriptor, readCollection(descriptor, Arrays.asList((Object[]) value))
|
||||
.toArray());
|
||||
bw.setValue(descriptor, readCollection(descriptor, Arrays.asList((Object[]) value)).toArray());
|
||||
} else if (value instanceof BasicDBList) {
|
||||
bw.setValue(descriptor, readCollection(descriptor, (BasicDBList) value));
|
||||
} else if (value instanceof DBObject) {
|
||||
bw.setValue(descriptor, readCompoundValue(descriptor, (DBObject) value));
|
||||
} else {
|
||||
LOG.warn("Unable to map compound DBObject field " + keyToUse + " to property "
|
||||
+ descriptor.getName()
|
||||
+ ". The field value should have been a 'DBObject.class' but was "
|
||||
+ value.getClass().getName());
|
||||
LOG.warn("Unable to map compound DBObject field " + keyToUse + " to property " + descriptor.getName()
|
||||
+ ". The field value should have been a 'DBObject.class' but was " + value.getClass().getName());
|
||||
}
|
||||
} else {
|
||||
bw.setValue(descriptor, value);
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Unable to map DBObject field " + keyToUse + " to property " + descriptor.getName()
|
||||
+ ". Skipping.");
|
||||
LOG.warn("Unable to map DBObject field " + keyToUse + " to property " + descriptor.getName() + ". Skipping.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -409,7 +406,7 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
/**
|
||||
* Reads the given collection values (that are {@link DBObject}s potentially) into a {@link Collection} of domain
|
||||
* objects.
|
||||
*
|
||||
*
|
||||
* @param descriptor
|
||||
* @param values
|
||||
* @return
|
||||
@@ -442,7 +439,7 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
|
||||
/**
|
||||
* Reads a compound value from the given {@link DBObject} for the given property.
|
||||
*
|
||||
*
|
||||
* @param pd
|
||||
* @param dbo
|
||||
* @return
|
||||
@@ -461,7 +458,7 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
/**
|
||||
* Create a {@link Map} instance. Will return a {@link HashMap} by default. Subclasses might want to override this
|
||||
* method to use a custom {@link Map} implementation.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected Map<String, Object> createMap() {
|
||||
@@ -470,7 +467,7 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
|
||||
/**
|
||||
* Reads every key/value pair from the {@link DBObject} into a {@link Map} instance.
|
||||
*
|
||||
*
|
||||
* @param pd
|
||||
* @param dbo
|
||||
* @param targetType
|
||||
@@ -503,9 +500,11 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
|
||||
|
||||
/**
|
||||
* Callback to allow customizing creation of a {@link MongoBeanWrapper}.
|
||||
*
|
||||
* @param target the target object to wrap
|
||||
* @param fieldAccess whether to use field access or property access
|
||||
*
|
||||
* @param target
|
||||
* the target object to wrap
|
||||
* @param fieldAccess
|
||||
* whether to use field access or property access
|
||||
* @return
|
||||
*/
|
||||
protected MongoBeanWrapper createWrapper(Object target, boolean fieldAccess) {
|
||||
|
||||
@@ -25,57 +25,57 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class Box {
|
||||
|
||||
private final Point first;
|
||||
private final Point second;
|
||||
private final Point first;
|
||||
private final Point second;
|
||||
|
||||
public Box(Point lowerLeft, Point upperRight) {
|
||||
Assert.notNull(lowerLeft);
|
||||
Assert.notNull(upperRight);
|
||||
this.first = lowerLeft;
|
||||
this.second = upperRight;
|
||||
}
|
||||
public Box(Point lowerLeft, Point upperRight) {
|
||||
Assert.notNull(lowerLeft);
|
||||
Assert.notNull(upperRight);
|
||||
this.first = lowerLeft;
|
||||
this.second = upperRight;
|
||||
}
|
||||
|
||||
public Box(double[] lowerLeft, double[] upperRight) {
|
||||
Assert.isTrue(lowerLeft.length == 2, "Point array has to have 2 elements!");
|
||||
Assert.isTrue(upperRight.length == 2, "Point array has to have 2 elements!");
|
||||
this.first = new Point(lowerLeft[0], lowerLeft[1]);
|
||||
this.second = new Point(upperRight[0], upperRight[1]);
|
||||
}
|
||||
public Box(double[] lowerLeft, double[] upperRight) {
|
||||
Assert.isTrue(lowerLeft.length == 2, "Point array has to have 2 elements!");
|
||||
Assert.isTrue(upperRight.length == 2, "Point array has to have 2 elements!");
|
||||
this.first = new Point(lowerLeft[0], lowerLeft[1]);
|
||||
this.second = new Point(upperRight[0], upperRight[1]);
|
||||
}
|
||||
|
||||
public Point getLowerLeft() {
|
||||
return first;
|
||||
}
|
||||
public Point getLowerLeft() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public Point getUpperRight() {
|
||||
return second;
|
||||
}
|
||||
public Point getUpperRight() {
|
||||
return second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Box [%s, %s]", first, second);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Box [%s, %s]", first, second);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 31;
|
||||
result += 17 * first.hashCode();
|
||||
result += 17 * second.hashCode();
|
||||
return result;
|
||||
}
|
||||
int result = 31;
|
||||
result += 17 * first.hashCode();
|
||||
result += 17 * second.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Box that = (Box) obj;
|
||||
return this.first.equals(that.first) && this.second.equals(that.second);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Box that = (Box) obj;
|
||||
return this.first.equals(that.first) && this.second.equals(that.second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,35 +19,36 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Represents a geospatial circle value
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class Circle {
|
||||
|
||||
private Point center;
|
||||
private double radius;
|
||||
|
||||
public Circle(Point center, double radius) {
|
||||
Assert.notNull(center);
|
||||
Assert.isTrue(radius >= 0, "Radius must not be negative!");
|
||||
this.center = center;
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public Circle(double centerX, double centerY, double radius) {
|
||||
this(new Point(centerX, centerY), radius);
|
||||
}
|
||||
private Point center;
|
||||
private double radius;
|
||||
|
||||
public Point getCenter() {
|
||||
return center;
|
||||
}
|
||||
public Circle(Point center, double radius) {
|
||||
Assert.notNull(center);
|
||||
Assert.isTrue(radius >= 0, "Radius must not be negative!");
|
||||
this.center = center;
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
public Circle(double centerX, double centerY, double radius) {
|
||||
this(new Point(centerX, centerY), radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Circle [center=%s, radius=%d]", center, radius);
|
||||
}
|
||||
public Point getCenter() {
|
||||
return center;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Circle [center=%s, radius=%d]", center, radius);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,70 +26,68 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class Point {
|
||||
|
||||
private final double x;
|
||||
private final double y;
|
||||
|
||||
@PersistenceConstructor
|
||||
public Point(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Point(Point point) {
|
||||
Assert.notNull(point);
|
||||
this.x = point.x;
|
||||
this.y = point.y;
|
||||
}
|
||||
private final double x;
|
||||
private final double y;
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
@PersistenceConstructor
|
||||
public Point(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double[] asArray() {
|
||||
return new double[] {x, y};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(x);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(y);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
public Point(Point point) {
|
||||
Assert.notNull(point);
|
||||
this.x = point.x;
|
||||
this.y = point.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Point other = (Point) obj;
|
||||
if (Double.doubleToLongBits(x) != Double
|
||||
.doubleToLongBits(other.x)) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(y) != Double
|
||||
.doubleToLongBits(other.y)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Point [latitude=%d, longitude=%d]", x, y);
|
||||
}
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double[] asArray() {
|
||||
return new double[] { x, y };
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(x);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(y);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Point other = (Point) obj;
|
||||
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x)) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Point [latitude=%d, longitude=%d]", x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,10 @@ import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Mark a class to use compound indexes.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Target({ ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CompoundIndex {
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@ import java.lang.annotation.Target;
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Target({ ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CompoundIndexes {
|
||||
|
||||
CompoundIndex[] value();
|
||||
CompoundIndex[] value();
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Mark a field to be indexed using MongoDB's geospatial indexing feature.
|
||||
*
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@@ -32,35 +32,35 @@ public @interface GeoSpatialIndexed {
|
||||
|
||||
/**
|
||||
* Name of the property in the document that contains the [x, y] or radial coordinates to index.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* Name of the collection in which to create the index.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String collection() default "";
|
||||
|
||||
/**
|
||||
* Minimum value for indexed values.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int min() default -180;
|
||||
|
||||
/**
|
||||
* Maximum value for indexed values.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int max() default 180;
|
||||
|
||||
/**
|
||||
* Bits of precision for boundary calculations.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int bits() default 26;
|
||||
|
||||
@@ -23,8 +23,8 @@ import com.mongodb.DBObject;
|
||||
*/
|
||||
public interface IndexDefinition {
|
||||
|
||||
DBObject getIndexKeys();
|
||||
DBObject getIndexKeys();
|
||||
|
||||
DBObject getIndexOptions();
|
||||
DBObject getIndexOptions();
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,5 @@ package org.springframework.data.document.mongodb.index;
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public enum IndexDirection {
|
||||
ASCENDING,
|
||||
DESCENDING;
|
||||
ASCENDING, DESCENDING;
|
||||
}
|
||||
|
||||
@@ -21,31 +21,31 @@ package org.springframework.data.document.mongodb.index;
|
||||
*/
|
||||
public abstract class IndexPredicate {
|
||||
|
||||
private String name;
|
||||
private IndexDirection direction = IndexDirection.ASCENDING;
|
||||
private boolean unique = false;
|
||||
private String name;
|
||||
private IndexDirection direction = IndexDirection.ASCENDING;
|
||||
private boolean unique = false;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public IndexDirection getDirection() {
|
||||
return direction;
|
||||
}
|
||||
public IndexDirection getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setDirection(IndexDirection direction) {
|
||||
this.direction = direction;
|
||||
}
|
||||
public void setDirection(IndexDirection direction) {
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public boolean isUnique() {
|
||||
return unique;
|
||||
}
|
||||
public boolean isUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
public void setUnique(boolean unique) {
|
||||
this.unique = unique;
|
||||
}
|
||||
public void setUnique(boolean unique) {
|
||||
this.unique = unique;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,22 +22,23 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Mark a field to be indexed using MongoDB's indexing feature.
|
||||
* Mark a field to be indexed using MongoDB's indexing feature.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Indexed {
|
||||
|
||||
boolean unique() default false;
|
||||
boolean unique() default false;
|
||||
|
||||
IndexDirection direction() default IndexDirection.ASCENDING;
|
||||
IndexDirection direction() default IndexDirection.ASCENDING;
|
||||
|
||||
boolean sparse() default false;
|
||||
boolean sparse() default false;
|
||||
|
||||
boolean dropDups() default false;
|
||||
boolean dropDups() default false;
|
||||
|
||||
String name() default "";
|
||||
String name() default "";
|
||||
|
||||
String collection() default "";
|
||||
String collection() default "";
|
||||
}
|
||||
|
||||
@@ -22,58 +22,58 @@ import org.springframework.data.mapping.model.PersistentEntity;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Mongo specific {@link PersistentEntity} implementation that adds Mongo specific meta-data such as the collection name
|
||||
* and the like.
|
||||
*
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements MongoPersistentEntity<T> {
|
||||
public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements
|
||||
MongoPersistentEntity<T> {
|
||||
|
||||
private final String collection;
|
||||
private final boolean isRootEntity;
|
||||
private final String collection;
|
||||
private final boolean isRootEntity;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicMongoPersistentEntity} with the given {@link TypeInformation}. Will
|
||||
* default the collection name to the entities simple type name.
|
||||
*
|
||||
* @param typeInformation
|
||||
*/
|
||||
public BasicMongoPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
|
||||
super(typeInformation);
|
||||
|
||||
Class<?> rawType = typeInformation.getType();
|
||||
String fallback = rawType.getSimpleName().toLowerCase();
|
||||
|
||||
if (rawType.isAnnotationPresent(Document.class)) {
|
||||
Document d = rawType.getAnnotation(Document.class);
|
||||
this.collection = StringUtils.hasText(d.collection()) ? d.collection() : fallback;
|
||||
this.isRootEntity = true;
|
||||
} else {
|
||||
this.collection = fallback;
|
||||
this.isRootEntity = false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link BasicMongoPersistentEntity} with the given {@link TypeInformation}. Will default the
|
||||
* collection name to the entities simple type name.
|
||||
*
|
||||
* @param typeInformation
|
||||
*/
|
||||
public BasicMongoPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
|
||||
/**
|
||||
* Returns the collection the entity should be stored in.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getCollection() {
|
||||
return collection;
|
||||
}
|
||||
super(typeInformation);
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicPersistentEntity#verify()
|
||||
*/
|
||||
@Override
|
||||
public void verify() {
|
||||
if (isRootEntity && idProperty == null) {
|
||||
throw new MappingException(String.format("Root entity %s has to have an id property!", getType().getName()));
|
||||
}
|
||||
}
|
||||
Class<?> rawType = typeInformation.getType();
|
||||
String fallback = rawType.getSimpleName().toLowerCase();
|
||||
|
||||
if (rawType.isAnnotationPresent(Document.class)) {
|
||||
Document d = rawType.getAnnotation(Document.class);
|
||||
this.collection = StringUtils.hasText(d.collection()) ? d.collection() : fallback;
|
||||
this.isRootEntity = true;
|
||||
} else {
|
||||
this.collection = fallback;
|
||||
this.isRootEntity = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collection the entity should be stored in.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicPersistentEntity#verify()
|
||||
*/
|
||||
@Override
|
||||
public void verify() {
|
||||
if (isRootEntity && idProperty == null) {
|
||||
throw new MappingException(String.format("Root entity %s has to have an id property!", getType().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,76 +28,73 @@ import org.springframework.data.mapping.model.Association;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Mongo specific
|
||||
* {@link org.springframework.data.mapping.model.PersistentProperty}
|
||||
* implementation.
|
||||
*
|
||||
* Mongo specific {@link org.springframework.data.mapping.model.PersistentProperty} implementation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class BasicMongoPersistentProperty extends AnnotationBasedPersistentProperty<MongoPersistentProperty> implements MongoPersistentProperty {
|
||||
public class BasicMongoPersistentProperty extends AnnotationBasedPersistentProperty<MongoPersistentProperty> implements
|
||||
MongoPersistentProperty {
|
||||
|
||||
private static final Set<Class<?>> SUPPORTED_ID_TYPES = new HashSet<Class<?>>();
|
||||
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<String>();
|
||||
private static final Set<Class<?>> SUPPORTED_ID_TYPES = new HashSet<Class<?>>();
|
||||
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<String>();
|
||||
|
||||
static {
|
||||
SUPPORTED_ID_TYPES.add(ObjectId.class);
|
||||
SUPPORTED_ID_TYPES.add(String.class);
|
||||
SUPPORTED_ID_TYPES.add(BigInteger.class);
|
||||
static {
|
||||
SUPPORTED_ID_TYPES.add(ObjectId.class);
|
||||
SUPPORTED_ID_TYPES.add(String.class);
|
||||
SUPPORTED_ID_TYPES.add(BigInteger.class);
|
||||
|
||||
SUPPORTED_ID_PROPERTY_NAMES.add("id");
|
||||
SUPPORTED_ID_PROPERTY_NAMES.add("_id");
|
||||
}
|
||||
SUPPORTED_ID_PROPERTY_NAMES.add("id");
|
||||
SUPPORTED_ID_PROPERTY_NAMES.add("_id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicMongoPersistentProperty}.
|
||||
*
|
||||
* @param field
|
||||
* @param propertyDescriptor
|
||||
* @param owningTypeInformation
|
||||
*/
|
||||
public BasicMongoPersistentProperty(Field field,
|
||||
PropertyDescriptor propertyDescriptor, MongoPersistentEntity<?> owner) {
|
||||
super(field, propertyDescriptor, owner);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.FooBasicPersistentProperty#isAssociation()
|
||||
*/
|
||||
@Override
|
||||
public boolean isAssociation() {
|
||||
return field.isAnnotationPresent(DBRef.class) || super.isAssociation();
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link BasicMongoPersistentProperty}.
|
||||
*
|
||||
* @param field
|
||||
* @param propertyDescriptor
|
||||
* @param owningTypeInformation
|
||||
*/
|
||||
public BasicMongoPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, MongoPersistentEntity<?> owner) {
|
||||
super(field, propertyDescriptor, owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Also considers fields as id that are of supported id type and name.
|
||||
*
|
||||
* @see #SUPPORTED_ID_PROPERTY_NAMES
|
||||
* @see #SUPPORTED_ID_TYPES
|
||||
*/
|
||||
@Override
|
||||
public boolean isIdProperty() {
|
||||
if (super.isIdProperty()) {
|
||||
return true;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.FooBasicPersistentProperty#isAssociation()
|
||||
*/
|
||||
@Override
|
||||
public boolean isAssociation() {
|
||||
return field.isAnnotationPresent(DBRef.class) || super.isAssociation();
|
||||
}
|
||||
|
||||
return SUPPORTED_ID_TYPES.contains(field.getType())
|
||||
&& SUPPORTED_ID_PROPERTY_NAMES.contains(field.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key to be used to store the value of the property inside a Mongo {@link DBObject}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getKey() {
|
||||
return isIdProperty() ? "_id" : getName();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.AbstractPersistentProperty#createAssociation()
|
||||
*/
|
||||
@Override
|
||||
protected Association<MongoPersistentProperty> createAssociation() {
|
||||
return new Association<MongoPersistentProperty>(this, null);
|
||||
}
|
||||
/**
|
||||
* Also considers fields as id that are of supported id type and name.
|
||||
*
|
||||
* @see #SUPPORTED_ID_PROPERTY_NAMES
|
||||
* @see #SUPPORTED_ID_TYPES
|
||||
*/
|
||||
@Override
|
||||
public boolean isIdProperty() {
|
||||
if (super.isIdProperty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return SUPPORTED_ID_TYPES.contains(field.getType()) && SUPPORTED_ID_PROPERTY_NAMES.contains(field.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key to be used to store the value of the property inside a Mongo {@link DBObject}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getKey() {
|
||||
return isIdProperty() ? "_id" : getName();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.AbstractPersistentProperty#createAssociation()
|
||||
*/
|
||||
@Override
|
||||
protected Association<MongoPersistentProperty> createAssociation() {
|
||||
return new Association<MongoPersistentProperty>(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,20 +24,19 @@ import java.lang.annotation.Target;
|
||||
import org.springframework.data.annotation.Reference;
|
||||
|
||||
/**
|
||||
* An annotation that indicates the annotated field is to be stored using a com.mongodb.DBRef
|
||||
* An annotation that indicates the annotated field is to be stored using a com.mongodb.DBRef
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({
|
||||
ElementType.FIELD
|
||||
})
|
||||
@Target({ ElementType.FIELD })
|
||||
@Reference
|
||||
public @interface DBRef {
|
||||
|
||||
String collection() default "";
|
||||
String collection() default "";
|
||||
|
||||
String id() default "";
|
||||
String id() default "";
|
||||
|
||||
String db() default "";
|
||||
String db() default "";
|
||||
|
||||
}
|
||||
|
||||
@@ -25,15 +25,14 @@ import org.springframework.data.annotation.Persistent;
|
||||
|
||||
/**
|
||||
* Identifies a domain object to be persisted to MongoDB.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Persistent
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({
|
||||
ElementType.TYPE
|
||||
})
|
||||
@Target({ ElementType.TYPE })
|
||||
public @interface Document {
|
||||
|
||||
String collection() default "";
|
||||
String collection() default "";
|
||||
|
||||
}
|
||||
|
||||
@@ -31,30 +31,31 @@ import org.springframework.data.util.TypeInformation;
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersistentEntity<?>, MongoPersistentProperty> {
|
||||
public MongoMappingContext() {
|
||||
augmentSimpleTypes();
|
||||
}
|
||||
public MongoMappingContext() {
|
||||
augmentSimpleTypes();
|
||||
}
|
||||
|
||||
protected void augmentSimpleTypes() {
|
||||
// Augment simpleTypes with MongoDB-specific classes
|
||||
Set<Class<?>> simpleTypes = MappingBeanHelper.getSimpleTypes();
|
||||
simpleTypes.add(com.mongodb.DBRef.class);
|
||||
simpleTypes.add(ObjectId.class);
|
||||
simpleTypes.add(CodeWScope.class);
|
||||
simpleTypes.add(Character.class);
|
||||
simpleTypes.add(BigInteger.class);
|
||||
}
|
||||
protected void augmentSimpleTypes() {
|
||||
// Augment simpleTypes with MongoDB-specific classes
|
||||
Set<Class<?>> simpleTypes = MappingBeanHelper.getSimpleTypes();
|
||||
simpleTypes.add(com.mongodb.DBRef.class);
|
||||
simpleTypes.add(ObjectId.class);
|
||||
simpleTypes.add(CodeWScope.class);
|
||||
simpleTypes.add(Character.class);
|
||||
simpleTypes.add(BigInteger.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, BasicMongoPersistentEntity<?> owner) {
|
||||
return new BasicMongoPersistentProperty(field, descriptor, owner);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation, org.springframework.data.mapping.model.MappingContext)
|
||||
*/
|
||||
@Override
|
||||
protected <T> BasicMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new BasicMongoPersistentEntity<T>(typeInformation);
|
||||
}
|
||||
@Override
|
||||
public MongoPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
BasicMongoPersistentEntity<?> owner) {
|
||||
return new BasicMongoPersistentProperty(field, descriptor, owner);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation, org.springframework.data.mapping.model.MappingContext)
|
||||
*/
|
||||
@Override
|
||||
protected <T> BasicMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new BasicMongoPersistentEntity<T>(typeInformation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ package org.springframework.data.document.mongodb.mapping;
|
||||
import org.springframework.data.mapping.model.PersistentEntity;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoPersistentEntity<T> extends PersistentEntity<T, MongoPersistentProperty> {
|
||||
|
||||
String getCollection();
|
||||
String getCollection();
|
||||
}
|
||||
|
||||
@@ -45,9 +45,9 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Component that inspects {@link BasicMongoPersistentEntity} instances contained in the given {@link MongoMappingContext}
|
||||
* for indexing metadata and ensures the indexes to be available.
|
||||
*
|
||||
* Component that inspects {@link BasicMongoPersistentEntity} instances contained in the given
|
||||
* {@link MongoMappingContext} for indexing metadata and ensures the indexes to be available.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@@ -64,7 +64,7 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
|
||||
Assert.notNull(mongoTemplate);
|
||||
Assert.notNull(mappingContext);
|
||||
this.mongoTemplate = mongoTemplate;
|
||||
|
||||
|
||||
for (MongoPersistentEntity<?> entity : mappingContext.getPersistentEntities()) {
|
||||
checkForIndexes(entity);
|
||||
}
|
||||
@@ -92,7 +92,8 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
|
||||
if ("".equals(indexColl)) {
|
||||
indexColl = entity.getCollection();
|
||||
}
|
||||
ensureIndex(indexColl, index.name(), index.def(), index.direction(), index.unique(), index.dropDups(), index.sparse());
|
||||
ensureIndex(indexColl, index.name(), index.def(), index.direction(), index.unique(), index.dropDups(),
|
||||
index.sparse());
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Created compound index " + index);
|
||||
}
|
||||
@@ -121,38 +122,32 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Created property index " + index);
|
||||
}
|
||||
} else if (field.isAnnotationPresent(GeoSpatialIndexed.class)) {
|
||||
} else if (field.isAnnotationPresent(GeoSpatialIndexed.class)) {
|
||||
|
||||
GeoSpatialIndexed index = field.getAnnotation(GeoSpatialIndexed.class);
|
||||
GeoSpatialIndexed index = field.getAnnotation(GeoSpatialIndexed.class);
|
||||
|
||||
GeospatialIndex indexObject = new GeospatialIndex(StringUtils.hasText(index.name()) ? index.name() : field
|
||||
.getName());
|
||||
indexObject.withMin(index.min()).withMax(index.max());
|
||||
GeospatialIndex indexObject = new GeospatialIndex(StringUtils.hasText(index.name()) ? index.name() : field
|
||||
.getName());
|
||||
indexObject.withMin(index.min()).withMax(index.max());
|
||||
|
||||
String collection = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();
|
||||
mongoTemplate.ensureIndex(collection, indexObject);
|
||||
String collection = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();
|
||||
mongoTemplate.ensureIndex(collection, indexObject);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("Created %s for entity %s in collection %s! ", indexObject, entity.getType(),
|
||||
collection));
|
||||
}
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("Created %s for entity %s in collection %s! ", indexObject, entity.getType(),
|
||||
collection));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
classesSeen.add(type);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected void ensureIndex(String collection,
|
||||
final String name,
|
||||
final String def,
|
||||
final IndexDirection direction,
|
||||
final boolean unique,
|
||||
final boolean dropDups,
|
||||
final boolean sparse) {
|
||||
protected void ensureIndex(String collection, final String name, final String def, final IndexDirection direction,
|
||||
final boolean unique, final boolean dropDups, final boolean sparse) {
|
||||
mongoTemplate.execute(collection, new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
DBObject defObj;
|
||||
@@ -163,7 +158,7 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
|
||||
defObj.put(name, (direction == IndexDirection.ASCENDING ? 1 : -1));
|
||||
}
|
||||
DBObject opts = new BasicDBObject();
|
||||
//opts.put("name", name + "_idx");
|
||||
// opts.put("name", name + "_idx");
|
||||
opts.put("dropDups", dropDups);
|
||||
opts.put("sparse", sparse);
|
||||
opts.put("unique", unique);
|
||||
|
||||
@@ -18,12 +18,10 @@ package org.springframework.data.document.mongodb.mapping;
|
||||
import org.springframework.data.mapping.model.PersistentProperty;
|
||||
|
||||
/**
|
||||
* Mongo specific
|
||||
* {@link org.springframework.data.mapping.model.PersistentProperty}
|
||||
* implementation.
|
||||
*
|
||||
* Mongo specific {@link org.springframework.data.mapping.model.PersistentProperty} implementation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoPersistentProperty extends PersistentProperty<MongoPersistentProperty> {
|
||||
String getKey();
|
||||
String getKey();
|
||||
}
|
||||
|
||||
@@ -27,79 +27,83 @@ import org.springframework.data.mapping.model.Association;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SimpleMongoMappingContext extends AbstractMappingContext<SimpleMongoMappingContext.SimpleMongoPersistentEntity<?>, MongoPersistentProperty> {
|
||||
public class SimpleMongoMappingContext extends
|
||||
AbstractMappingContext<SimpleMongoMappingContext.SimpleMongoPersistentEntity<?>, MongoPersistentProperty> {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected <T> SimpleMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new SimpleMongoPersistentEntity<T>(typeInformation);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected <T> SimpleMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new SimpleMongoPersistentEntity<T>(typeInformation);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.util.TypeInformation, org.springframework.data.mapping.BasicPersistentEntity)
|
||||
*/
|
||||
@Override
|
||||
protected SimplePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, SimpleMongoPersistentEntity<?> owner) {
|
||||
return new SimplePersistentProperty(field, descriptor, owner);
|
||||
}
|
||||
|
||||
static class SimplePersistentProperty extends AbstractPersistentProperty<MongoPersistentProperty> implements MongoPersistentProperty {
|
||||
|
||||
private static final List<String> ID_FIELD_NAMES = Arrays.asList("id", "_id");
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.util.TypeInformation, org.springframework.data.mapping.BasicPersistentEntity)
|
||||
*/
|
||||
@Override
|
||||
protected SimplePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
SimpleMongoPersistentEntity<?> owner) {
|
||||
return new SimplePersistentProperty(field, descriptor, owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimplePersistentProperty}.
|
||||
*
|
||||
* @param field
|
||||
* @param propertyDescriptor
|
||||
* @param information
|
||||
*/
|
||||
public SimplePersistentProperty(Field field, PropertyDescriptor propertyDescriptor, MongoPersistentEntity<?> owner) {
|
||||
super(field, propertyDescriptor, owner);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicPersistentProperty#isIdProperty()
|
||||
*/
|
||||
public boolean isIdProperty() {
|
||||
return ID_FIELD_NAMES.contains(field.getName());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.mapping.MongoPersistentProperty#getKey()
|
||||
*/
|
||||
public String getKey() {
|
||||
return isIdProperty() ? "_id" : getName();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.AbstractPersistentProperty#createAssociation()
|
||||
*/
|
||||
@Override
|
||||
protected Association<MongoPersistentProperty> createAssociation() {
|
||||
return new Association<MongoPersistentProperty>(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
static class SimpleMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements MongoPersistentEntity<T> {
|
||||
static class SimplePersistentProperty extends AbstractPersistentProperty<MongoPersistentProperty> implements
|
||||
MongoPersistentProperty {
|
||||
|
||||
/**
|
||||
* @param information
|
||||
*/
|
||||
public SimpleMongoPersistentEntity(TypeInformation<T> information) {
|
||||
super(information);
|
||||
}
|
||||
private static final List<String> ID_FIELD_NAMES = Arrays.asList("id", "_id");
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.mapping.MongoPersistentEntity#getCollection()
|
||||
*/
|
||||
public String getCollection() {
|
||||
return getType().getSimpleName();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link SimplePersistentProperty}.
|
||||
*
|
||||
* @param field
|
||||
* @param propertyDescriptor
|
||||
* @param information
|
||||
*/
|
||||
public SimplePersistentProperty(Field field, PropertyDescriptor propertyDescriptor, MongoPersistentEntity<?> owner) {
|
||||
super(field, propertyDescriptor, owner);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicPersistentProperty#isIdProperty()
|
||||
*/
|
||||
public boolean isIdProperty() {
|
||||
return ID_FIELD_NAMES.contains(field.getName());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.mapping.MongoPersistentProperty#getKey()
|
||||
*/
|
||||
public String getKey() {
|
||||
return isIdProperty() ? "_id" : getName();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.AbstractPersistentProperty#createAssociation()
|
||||
*/
|
||||
@Override
|
||||
protected Association<MongoPersistentProperty> createAssociation() {
|
||||
return new Association<MongoPersistentProperty>(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
static class SimpleMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements
|
||||
MongoPersistentEntity<T> {
|
||||
|
||||
/**
|
||||
* @param information
|
||||
*/
|
||||
public SimpleMongoPersistentEntity(TypeInformation<T> information) {
|
||||
super(information);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.mapping.MongoPersistentEntity#getCollection()
|
||||
*/
|
||||
public String getCollection() {
|
||||
return getType().getSimpleName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,59 +27,59 @@ import org.springframework.context.ApplicationListener;
|
||||
*/
|
||||
public abstract class AbstractMappingEventListener<T extends ApplicationEvent, E> implements ApplicationListener<T> {
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public void onApplicationEvent(T appEvent) {
|
||||
if (appEvent instanceof MongoMappingEvent) {
|
||||
try {
|
||||
MongoMappingEvent<E> event = (MongoMappingEvent<E>) appEvent;
|
||||
if (event instanceof BeforeConvertEvent) {
|
||||
onBeforeConvert(event.getSource());
|
||||
} else if (event instanceof BeforeSaveEvent) {
|
||||
onBeforeSave(event.getSource(), event.getDBObject());
|
||||
} else if (event instanceof AfterSaveEvent) {
|
||||
onAfterSave(event.getSource(), event.getDBObject());
|
||||
} else if (event instanceof AfterLoadEvent) {
|
||||
onAfterLoad((DBObject) event.getSource());
|
||||
} else if (event instanceof AfterConvertEvent) {
|
||||
onAfterConvert(event.getDBObject(), event.getSource());
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
// Not a mapping event for this entity, apparently.
|
||||
// Just ignore it for now.
|
||||
}
|
||||
}
|
||||
}
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public void onApplicationEvent(T appEvent) {
|
||||
if (appEvent instanceof MongoMappingEvent) {
|
||||
try {
|
||||
MongoMappingEvent<E> event = (MongoMappingEvent<E>) appEvent;
|
||||
if (event instanceof BeforeConvertEvent) {
|
||||
onBeforeConvert(event.getSource());
|
||||
} else if (event instanceof BeforeSaveEvent) {
|
||||
onBeforeSave(event.getSource(), event.getDBObject());
|
||||
} else if (event instanceof AfterSaveEvent) {
|
||||
onAfterSave(event.getSource(), event.getDBObject());
|
||||
} else if (event instanceof AfterLoadEvent) {
|
||||
onAfterLoad((DBObject) event.getSource());
|
||||
} else if (event instanceof AfterConvertEvent) {
|
||||
onAfterConvert(event.getDBObject(), event.getSource());
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
// Not a mapping event for this entity, apparently.
|
||||
// Just ignore it for now.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onBeforeConvert(E source) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onBeforeConvert(" + source + ")");
|
||||
}
|
||||
}
|
||||
public void onBeforeConvert(E source) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onBeforeConvert(" + source + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void onBeforeSave(E source, DBObject dbo) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onBeforeSave(" + source + ", " + dbo + ")");
|
||||
}
|
||||
}
|
||||
public void onBeforeSave(E source, DBObject dbo) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onBeforeSave(" + source + ", " + dbo + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void onAfterSave(E source, DBObject dbo) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onAfterSave(" + source + ", " + dbo + ")");
|
||||
}
|
||||
}
|
||||
public void onAfterSave(E source, DBObject dbo) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onAfterSave(" + source + ", " + dbo + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onAfterLoad(" + dbo + ")");
|
||||
}
|
||||
}
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onAfterLoad(" + dbo + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void onAfterConvert(DBObject dbo, E source) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onAfterConvert(" + dbo + "," + source + ")");
|
||||
}
|
||||
}
|
||||
public void onAfterConvert(DBObject dbo, E source) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("onAfterConvert(" + dbo + "," + source + ")");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ import com.mongodb.DBObject;
|
||||
*/
|
||||
public class AfterConvertEvent<E> extends MongoMappingEvent<E> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AfterConvertEvent(DBObject dbo, E source) {
|
||||
super(source, dbo);
|
||||
}
|
||||
public AfterConvertEvent(DBObject dbo, E source) {
|
||||
super(source, dbo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ package org.springframework.data.document.mongodb.mapping.event;
|
||||
*/
|
||||
public class AfterLoadEvent<DBObject> extends MongoMappingEvent<DBObject> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AfterLoadEvent(DBObject dbo) {
|
||||
super(dbo, null);
|
||||
}
|
||||
public AfterLoadEvent(DBObject dbo) {
|
||||
super(dbo, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ import org.springframework.data.mapping.model.PersistentEntity;
|
||||
*/
|
||||
public class AfterSaveEvent<E> extends MongoMappingEvent<E> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AfterSaveEvent(E source, DBObject dbo) {
|
||||
super(source, dbo);
|
||||
}
|
||||
public AfterSaveEvent(E source, DBObject dbo) {
|
||||
super(source, dbo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,10 +21,9 @@ package org.springframework.data.document.mongodb.mapping.event;
|
||||
*/
|
||||
public class BeforeConvertEvent<T> extends MongoMappingEvent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public BeforeConvertEvent(T source) {
|
||||
super(source, null);
|
||||
}
|
||||
public BeforeConvertEvent(T source) {
|
||||
super(source, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@ import com.mongodb.DBObject;
|
||||
*/
|
||||
public class BeforeSaveEvent<E> extends MongoMappingEvent<E> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public BeforeSaveEvent(E source, DBObject dbo) {
|
||||
super(source, dbo);
|
||||
}
|
||||
public BeforeSaveEvent(E source, DBObject dbo) {
|
||||
super(source, dbo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,21 +24,21 @@ import org.springframework.context.ApplicationEvent;
|
||||
*/
|
||||
public class MongoMappingEvent<T> extends ApplicationEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final DBObject dbo;
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final DBObject dbo;
|
||||
|
||||
public MongoMappingEvent(T source, DBObject dbo) {
|
||||
super(source);
|
||||
this.dbo = dbo;
|
||||
}
|
||||
public MongoMappingEvent(T source, DBObject dbo) {
|
||||
super(source);
|
||||
this.dbo = dbo;
|
||||
}
|
||||
|
||||
public DBObject getDBObject() {
|
||||
return dbo;
|
||||
}
|
||||
public DBObject getDBObject() {
|
||||
return dbo;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public T getSource() {
|
||||
return (T) super.getSource();
|
||||
}
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Override
|
||||
public T getSource() {
|
||||
return (T) super.getSource();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,47 +25,48 @@ import org.springframework.data.document.mongodb.MongoDbUtils;
|
||||
|
||||
/**
|
||||
* Base class to encapsulate common configuration settings when connecting to a database
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
public abstract class AbstractMonitor {
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
protected Mongo mongo;
|
||||
private String username;
|
||||
private String password;
|
||||
protected Mongo mongo;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Sets the username to use to connect to the Mongo database
|
||||
*
|
||||
* @param username
|
||||
* The username to use
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the username to use to connect to the Mongo database
|
||||
*
|
||||
* @param username The username to use
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
/**
|
||||
* Sets the password to use to authenticate with the Mongo database.
|
||||
*
|
||||
* @param password
|
||||
* The password to use
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
|
||||
/**
|
||||
* Sets the password to use to authenticate with the Mongo database.
|
||||
*
|
||||
* @param password The password to use
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
this.password = password;
|
||||
}
|
||||
public CommandResult getServerStatus() {
|
||||
CommandResult result = getDb("admin").command("serverStatus");
|
||||
if (!result.ok()) {
|
||||
logger.error("Could not query for server status. Command Result = " + result);
|
||||
throw new MongoException("could not query for server status. Command Result = " + result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public CommandResult getServerStatus() {
|
||||
CommandResult result = getDb("admin").command("serverStatus");
|
||||
if (!result.ok()) {
|
||||
logger.error("Could not query for server status. Command Result = " + result);
|
||||
throw new MongoException("could not query for server status. Command Result = " + result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public DB getDb(String databaseName) {
|
||||
return MongoDbUtils.getDB(mongo, databaseName, username, password == null ? null : password.toCharArray());
|
||||
}
|
||||
public DB getDb(String databaseName) {
|
||||
return MongoDbUtils.getDB(mongo, databaseName, username, password == null ? null : password.toCharArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,45 +23,45 @@ import org.springframework.jmx.support.MetricType;
|
||||
|
||||
/**
|
||||
* JMX Metrics for assertions
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
@ManagedResource(description = "Assertion Metrics")
|
||||
public class AssertMetrics extends AbstractMonitor {
|
||||
|
||||
public AssertMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
public AssertMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Regular")
|
||||
public int getRegular() {
|
||||
return getBtree("regular");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Regular")
|
||||
public int getRegular() {
|
||||
return getBtree("regular");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Warning")
|
||||
public int getWarning() {
|
||||
return getBtree("warning");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Warning")
|
||||
public int getWarning() {
|
||||
return getBtree("warning");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Msg")
|
||||
public int getMsg() {
|
||||
return getBtree("msg");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Msg")
|
||||
public int getMsg() {
|
||||
return getBtree("msg");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "User")
|
||||
public int getUser() {
|
||||
return getBtree("user");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "User")
|
||||
public int getUser() {
|
||||
return getBtree("user");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Rollovers")
|
||||
public int getRollovers() {
|
||||
return getBtree("rollovers");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Rollovers")
|
||||
public int getRollovers() {
|
||||
return getBtree("rollovers");
|
||||
}
|
||||
|
||||
private int getBtree(String key) {
|
||||
DBObject asserts = (DBObject) getServerStatus().get("asserts");
|
||||
//Class c = btree.get(key).getClass();
|
||||
return (Integer) asserts.get(key);
|
||||
}
|
||||
private int getBtree(String key) {
|
||||
DBObject asserts = (DBObject) getServerStatus().get("asserts");
|
||||
// Class c = btree.get(key).getClass();
|
||||
return (Integer) asserts.get(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,54 +25,51 @@ import org.springframework.jmx.support.MetricType;
|
||||
|
||||
/**
|
||||
* JMX Metrics for Background Flushing
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
@ManagedResource(description = "Background Flushing Metrics")
|
||||
public class BackgroundFlushingMetrics extends AbstractMonitor {
|
||||
|
||||
public BackgroundFlushingMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
public BackgroundFlushingMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Flushes")
|
||||
public int getFlushes() {
|
||||
return getFlushingData("flushes", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Flushes")
|
||||
public int getFlushes() {
|
||||
return getFlushingData("flushes", java.lang.Integer.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Total ms", unit = "ms")
|
||||
public int getTotalMs() {
|
||||
return getFlushingData("total_ms", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Total ms", unit = "ms")
|
||||
public int getTotalMs() {
|
||||
return getFlushingData("total_ms", java.lang.Integer.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Average ms", unit = "ms")
|
||||
public double getAverageMs() {
|
||||
return getFlushingData("average_ms", java.lang.Double.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Average ms", unit = "ms")
|
||||
public double getAverageMs() {
|
||||
return getFlushingData("average_ms", java.lang.Double.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Last Ms", unit = "ms")
|
||||
public int getLastMs() {
|
||||
return getFlushingData("last_ms", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Last Ms", unit = "ms")
|
||||
public int getLastMs() {
|
||||
return getFlushingData("last_ms", java.lang.Integer.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Last finished")
|
||||
public Date getLastFinished() {
|
||||
return getLast();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getFlushingData(String key, Class<T> targetClass) {
|
||||
DBObject mem = (DBObject) getServerStatus().get("backgroundFlushing");
|
||||
return (T) mem.get(key);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Last finished")
|
||||
public Date getLastFinished() {
|
||||
return getLast();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getFlushingData(String key, Class<T> targetClass) {
|
||||
DBObject mem = (DBObject) getServerStatus().get("backgroundFlushing");
|
||||
return (T) mem.get(key);
|
||||
}
|
||||
|
||||
private Date getLast() {
|
||||
DBObject bgFlush = (DBObject) getServerStatus().get("backgroundFlushing");
|
||||
Date lastFinished = (Date) bgFlush.get("last_finished");
|
||||
return lastFinished;
|
||||
}
|
||||
|
||||
private Date getLast() {
|
||||
DBObject bgFlush = (DBObject) getServerStatus().get("backgroundFlushing");
|
||||
Date lastFinished = (Date) bgFlush.get("last_finished");
|
||||
return lastFinished;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,52 +23,52 @@ import org.springframework.jmx.support.MetricType;
|
||||
|
||||
/**
|
||||
* JMX Metrics for B-tree index counters
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
@ManagedResource(description = "Btree Metrics")
|
||||
public class BtreeIndexCounters extends AbstractMonitor {
|
||||
|
||||
public BtreeIndexCounters(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
public BtreeIndexCounters(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Accesses")
|
||||
public int getAccesses() {
|
||||
return getBtree("accesses");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Accesses")
|
||||
public int getAccesses() {
|
||||
return getBtree("accesses");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Hits")
|
||||
public int getHits() {
|
||||
return getBtree("hits");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Hits")
|
||||
public int getHits() {
|
||||
return getBtree("hits");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Misses")
|
||||
public int getMisses() {
|
||||
return getBtree("misses");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Misses")
|
||||
public int getMisses() {
|
||||
return getBtree("misses");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Resets")
|
||||
public int getResets() {
|
||||
return getBtree("resets");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Resets")
|
||||
public int getResets() {
|
||||
return getBtree("resets");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Miss Ratio")
|
||||
public int getMissRatio() {
|
||||
return getBtree("missRatio");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Miss Ratio")
|
||||
public int getMissRatio() {
|
||||
return getBtree("missRatio");
|
||||
}
|
||||
|
||||
private int getBtree(String key) {
|
||||
DBObject indexCounters = (DBObject) getServerStatus().get("indexCounters");
|
||||
if (indexCounters.get("note") != null) {
|
||||
String message = (String) indexCounters.get("note");
|
||||
if (message.contains("not supported")) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
DBObject btree = (DBObject) indexCounters.get("btree");
|
||||
//Class c = btree.get(key).getClass();
|
||||
return (Integer) btree.get(key);
|
||||
}
|
||||
private int getBtree(String key) {
|
||||
DBObject indexCounters = (DBObject) getServerStatus().get("indexCounters");
|
||||
if (indexCounters.get("note") != null) {
|
||||
String message = (String) indexCounters.get("note");
|
||||
if (message.contains("not supported")) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
DBObject btree = (DBObject) indexCounters.get("btree");
|
||||
// Class c = btree.get(key).getClass();
|
||||
return (Integer) btree.get(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,31 +23,31 @@ import org.springframework.jmx.support.MetricType;
|
||||
|
||||
/**
|
||||
* JMX Metrics for Connections
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
@ManagedResource(description = "Connection metrics")
|
||||
public class ConnectionMetrics extends AbstractMonitor {
|
||||
|
||||
public ConnectionMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
public ConnectionMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Current Connections")
|
||||
public int getCurrent() {
|
||||
return getConnectionData("current", java.lang.Integer.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Current Connections")
|
||||
public int getCurrent() {
|
||||
return getConnectionData("current", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Available Connections")
|
||||
public int getAvailable() {
|
||||
return getConnectionData("available", java.lang.Integer.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Available Connections")
|
||||
public int getAvailable() {
|
||||
return getConnectionData("available", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getConnectionData(String key, Class<T> targetClass) {
|
||||
DBObject mem = (DBObject) getServerStatus().get("connections");
|
||||
//Class c = mem.get(key).getClass();
|
||||
return (T) mem.get(key);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getConnectionData(String key, Class<T> targetClass) {
|
||||
DBObject mem = (DBObject) getServerStatus().get("connections");
|
||||
// Class c = mem.get(key).getClass();
|
||||
return (T) mem.get(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,57 +23,55 @@ import org.springframework.jmx.support.MetricType;
|
||||
|
||||
/**
|
||||
* JMX Metrics for Global Locks
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
@ManagedResource(description = "Global Lock Metrics")
|
||||
public class GlobalLockMetrics extends AbstractMonitor {
|
||||
|
||||
public GlobalLockMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
public GlobalLockMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Total time")
|
||||
public double getTotalTime() {
|
||||
return getGlobalLockData("totalTime", java.lang.Double.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Total time")
|
||||
public double getTotalTime() {
|
||||
return getGlobalLockData("totalTime", java.lang.Double.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Lock time", unit = "s")
|
||||
public double getLockTime() {
|
||||
return getGlobalLockData("lockTime", java.lang.Double.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Lock time", unit = "s")
|
||||
public double getLockTime() {
|
||||
return getGlobalLockData("lockTime", java.lang.Double.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Lock time")
|
||||
public double getLockTimeRatio() {
|
||||
return getGlobalLockData("ratio", java.lang.Double.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Lock time")
|
||||
public double getLockTimeRatio() {
|
||||
return getGlobalLockData("ratio", java.lang.Double.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Current Queue")
|
||||
public int getCurrentQueueTotal() {
|
||||
return getCurrentQueue("total");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Reader Queue")
|
||||
public int getCurrentQueueReaders() {
|
||||
return getCurrentQueue("readers");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Current Queue")
|
||||
public int getCurrentQueueTotal() {
|
||||
return getCurrentQueue("total");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Writer Queue")
|
||||
public int getCurrentQueueWriters() {
|
||||
return getCurrentQueue("writers");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Reader Queue")
|
||||
public int getCurrentQueueReaders() {
|
||||
return getCurrentQueue("readers");
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getGlobalLockData(String key, Class<T> targetClass) {
|
||||
DBObject globalLock = (DBObject) getServerStatus().get("globalLock");
|
||||
return (T) globalLock.get(key);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Writer Queue")
|
||||
public int getCurrentQueueWriters() {
|
||||
return getCurrentQueue("writers");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getGlobalLockData(String key, Class<T> targetClass) {
|
||||
DBObject globalLock = (DBObject) getServerStatus().get("globalLock");
|
||||
return (T) globalLock.get(key);
|
||||
}
|
||||
|
||||
private int getCurrentQueue(String key) {
|
||||
DBObject globalLock = (DBObject) getServerStatus().get("globalLock");
|
||||
DBObject currentQueue = (DBObject) globalLock.get("currentQueue");
|
||||
return (Integer) currentQueue.get(key);
|
||||
}
|
||||
private int getCurrentQueue(String key) {
|
||||
DBObject globalLock = (DBObject) getServerStatus().get("globalLock");
|
||||
DBObject currentQueue = (DBObject) globalLock.get("currentQueue");
|
||||
return (Integer) currentQueue.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,50 +23,46 @@ import org.springframework.jmx.support.MetricType;
|
||||
|
||||
/**
|
||||
* JMX Metrics for Memory
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
@ManagedResource(description = "Memory Metrics")
|
||||
public class MemoryMetrics extends AbstractMonitor {
|
||||
|
||||
public MemoryMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
public MemoryMetrics(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Memory address size")
|
||||
public int getBits() {
|
||||
return getMemData("bits", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Memory address size")
|
||||
public int getBits() {
|
||||
return getMemData("bits", java.lang.Integer.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Resident in Physical Memory", unit = "MB")
|
||||
public int getResidentSpace() {
|
||||
return getMemData("resident", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Resident in Physical Memory", unit = "MB")
|
||||
public int getResidentSpace() {
|
||||
return getMemData("resident", java.lang.Integer.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Virtual Address Space", unit = "MB")
|
||||
public int getVirtualAddressSpace() {
|
||||
return getMemData("virtual", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Virtual Address Space", unit = "MB")
|
||||
public int getVirtualAddressSpace() {
|
||||
return getMemData("virtual", java.lang.Integer.class);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Is memory info supported on this platform")
|
||||
public boolean getMemoryInfoSupported() {
|
||||
return getMemData("supported", java.lang.Boolean.class);
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Is memory info supported on this platform")
|
||||
public boolean getMemoryInfoSupported() {
|
||||
return getMemData("supported", java.lang.Boolean.class);
|
||||
}
|
||||
|
||||
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Memory Mapped Space", unit = "MB")
|
||||
public int getMemoryMappedSpace() {
|
||||
return getMemData("mapped", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getMemData(String key, Class<T> targetClass) {
|
||||
DBObject mem = (DBObject) getServerStatus().get("mem");
|
||||
//Class c = mem.get(key).getClass();
|
||||
return (T) mem.get(key);
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Memory Mapped Space", unit = "MB")
|
||||
public int getMemoryMappedSpace() {
|
||||
return getMemData("mapped", java.lang.Integer.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getMemData(String key, Class<T> targetClass) {
|
||||
DBObject mem = (DBObject) getServerStatus().get("mem");
|
||||
// Class c = mem.get(key).getClass();
|
||||
return (T) mem.get(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,49 +23,48 @@ import org.springframework.jmx.support.MetricType;
|
||||
|
||||
/**
|
||||
* JMX Metrics for Operation counters
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
@ManagedResource(description = "Operation Counters")
|
||||
public class OperationCounters extends AbstractMonitor {
|
||||
|
||||
public OperationCounters(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
public OperationCounters(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Insert operation count")
|
||||
public int getInsertCount() {
|
||||
return getOpCounter("insert");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Insert operation count")
|
||||
public int getInsertCount() {
|
||||
return getOpCounter("insert");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Query operation count")
|
||||
public int getQueryCount() {
|
||||
return getOpCounter("query");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Query operation count")
|
||||
public int getQueryCount() {
|
||||
return getOpCounter("query");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Update operation count")
|
||||
public int getUpdateCount() {
|
||||
return getOpCounter("update");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Update operation count")
|
||||
public int getUpdateCount() {
|
||||
return getOpCounter("update");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Delete operation count")
|
||||
public int getDeleteCount() {
|
||||
return getOpCounter("delete");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Delete operation count")
|
||||
public int getDeleteCount() {
|
||||
return getOpCounter("delete");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "GetMore operation count")
|
||||
public int getGetMoreCount() {
|
||||
return getOpCounter("getmore");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "GetMore operation count")
|
||||
public int getGetMoreCount() {
|
||||
return getOpCounter("getmore");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Command operation count")
|
||||
public int getCommandCount() {
|
||||
return getOpCounter("command");
|
||||
}
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Command operation count")
|
||||
public int getCommandCount() {
|
||||
return getOpCounter("command");
|
||||
}
|
||||
|
||||
private int getOpCounter(String key) {
|
||||
DBObject opCounters = (DBObject) getServerStatus().get("opcounters");
|
||||
return (Integer) opCounters.get(key);
|
||||
}
|
||||
private int getOpCounter(String key) {
|
||||
DBObject opCounters = (DBObject) getServerStatus().get("opcounters");
|
||||
return (Integer) opCounters.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,41 +26,39 @@ import org.springframework.jmx.support.MetricType;
|
||||
|
||||
/**
|
||||
* Expose basic server information via JMX
|
||||
*
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
@ManagedResource(description = "Server Information")
|
||||
public class ServerInfo extends AbstractMonitor {
|
||||
|
||||
public ServerInfo(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
public ServerInfo(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
@ManagedOperation(description = "Server host name")
|
||||
public String getHostName() throws UnknownHostException {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
}
|
||||
|
||||
@ManagedOperation(description = "Server host name")
|
||||
public String getHostName() throws UnknownHostException {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
}
|
||||
@ManagedMetric(displayName = "Uptime Estimate")
|
||||
public double getUptimeEstimate() {
|
||||
return (Double) getServerStatus().get("uptimeEstimate");
|
||||
}
|
||||
|
||||
@ManagedMetric(displayName = "Uptime Estimate")
|
||||
public double getUptimeEstimate() {
|
||||
return (Double) getServerStatus().get("uptimeEstimate");
|
||||
}
|
||||
@ManagedOperation(description = "MongoDB Server Version")
|
||||
public String getVersion() {
|
||||
return (String) getServerStatus().get("version");
|
||||
}
|
||||
|
||||
@ManagedOperation(description = "MongoDB Server Version")
|
||||
public String getVersion() {
|
||||
return (String) getServerStatus().get("version");
|
||||
}
|
||||
@ManagedOperation(description = "Local Time")
|
||||
public String getLocalTime() {
|
||||
return (String) getServerStatus().get("localTime");
|
||||
}
|
||||
|
||||
@ManagedOperation(description = "Local Time")
|
||||
public String getLocalTime() {
|
||||
return (String) getServerStatus().get("localTime");
|
||||
}
|
||||
|
||||
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Server uptime in seconds", unit = "seconds")
|
||||
public double getUptime() {
|
||||
return (Double) getServerStatus().get("uptime");
|
||||
}
|
||||
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "Server uptime in seconds", unit = "seconds")
|
||||
public double getUptime() {
|
||||
return (Double) getServerStatus().get("uptime");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
* MongoDB specific JMX monitoring support.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb.monitor;
|
||||
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
* MongoDB core support.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
|
||||
@@ -20,72 +20,72 @@ import com.mongodb.util.JSON;
|
||||
|
||||
public class BasicQuery extends Query {
|
||||
|
||||
private DBObject queryObject = null;
|
||||
private DBObject queryObject = null;
|
||||
|
||||
private DBObject fieldsObject = null;
|
||||
private DBObject fieldsObject = null;
|
||||
|
||||
private DBObject sortObject = null;
|
||||
private DBObject sortObject = null;
|
||||
|
||||
private int skip;
|
||||
private int skip;
|
||||
|
||||
private int limit;
|
||||
private int limit;
|
||||
|
||||
public BasicQuery(String query) {
|
||||
super();
|
||||
this.queryObject = (DBObject) JSON.parse(query);
|
||||
}
|
||||
public BasicQuery(String query) {
|
||||
super();
|
||||
this.queryObject = (DBObject) JSON.parse(query);
|
||||
}
|
||||
|
||||
public BasicQuery(DBObject queryObject) {
|
||||
super();
|
||||
this.queryObject = queryObject;
|
||||
}
|
||||
public BasicQuery(DBObject queryObject) {
|
||||
super();
|
||||
this.queryObject = queryObject;
|
||||
}
|
||||
|
||||
public BasicQuery(String query, String fields) {
|
||||
this.queryObject = (DBObject) JSON.parse(query);
|
||||
this.fieldsObject = (DBObject) JSON.parse(fields);
|
||||
}
|
||||
public BasicQuery(String query, String fields) {
|
||||
this.queryObject = (DBObject) JSON.parse(query);
|
||||
this.fieldsObject = (DBObject) JSON.parse(fields);
|
||||
}
|
||||
|
||||
public BasicQuery(DBObject queryObject, DBObject fieldsObject) {
|
||||
this.queryObject = queryObject;
|
||||
this.fieldsObject = fieldsObject;
|
||||
}
|
||||
public BasicQuery(DBObject queryObject, DBObject fieldsObject) {
|
||||
this.queryObject = queryObject;
|
||||
this.fieldsObject = fieldsObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query addCriteria(Criteria criteria) {
|
||||
this.queryObject.putAll(criteria.getCriteriaObject());
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public Query addCriteria(Criteria criteria) {
|
||||
this.queryObject.putAll(criteria.getCriteriaObject());
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getQueryObject() {
|
||||
return this.queryObject;
|
||||
}
|
||||
public DBObject getQueryObject() {
|
||||
return this.queryObject;
|
||||
}
|
||||
|
||||
public DBObject getFieldsObject() {
|
||||
return fieldsObject;
|
||||
}
|
||||
public DBObject getFieldsObject() {
|
||||
return fieldsObject;
|
||||
}
|
||||
|
||||
public DBObject getSortObject() {
|
||||
return sortObject;
|
||||
}
|
||||
public DBObject getSortObject() {
|
||||
return sortObject;
|
||||
}
|
||||
|
||||
public void setSortObject(DBObject sortObject) {
|
||||
this.sortObject = sortObject;
|
||||
}
|
||||
public void setSortObject(DBObject sortObject) {
|
||||
this.sortObject = sortObject;
|
||||
}
|
||||
|
||||
public int getSkip() {
|
||||
return skip;
|
||||
}
|
||||
public int getSkip() {
|
||||
return skip;
|
||||
}
|
||||
|
||||
public void setSkip(int skip) {
|
||||
this.skip = skip;
|
||||
}
|
||||
public void setSkip(int skip) {
|
||||
this.skip = skip;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return this.limit;
|
||||
}
|
||||
public int getLimit() {
|
||||
return this.limit;
|
||||
}
|
||||
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,398 +30,401 @@ import org.springframework.data.document.mongodb.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Custom "not-null" object as we have to be able to work with {@literal null} values as well.
|
||||
*/
|
||||
private static final Object NOT_SET = new Object();
|
||||
|
||||
private String key;
|
||||
/**
|
||||
* Custom "not-null" object as we have to be able to work with {@literal null} values as well.
|
||||
*/
|
||||
private static final Object NOT_SET = new Object();
|
||||
|
||||
private List<Criteria> criteriaChain;
|
||||
private String key;
|
||||
|
||||
private LinkedHashMap<String, Object> criteria = new LinkedHashMap<String, Object>();
|
||||
private List<Criteria> criteriaChain;
|
||||
|
||||
private Object isValue = NOT_SET;
|
||||
private LinkedHashMap<String, Object> criteria = new LinkedHashMap<String, Object>();
|
||||
|
||||
public Criteria(String key) {
|
||||
this.criteriaChain = new ArrayList<Criteria>();
|
||||
this.criteriaChain.add(this);
|
||||
this.key = key;
|
||||
}
|
||||
private Object isValue = NOT_SET;
|
||||
|
||||
protected Criteria(List<Criteria> criteriaChain, String key) {
|
||||
this.criteriaChain = criteriaChain;
|
||||
this.criteriaChain.add(this);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static factory method to create a Criteria using the provided key
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static Criteria where(String key) {
|
||||
return new Criteria(key);
|
||||
}
|
||||
|
||||
public static Criteria whereId() {
|
||||
return new Criteria("id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Static factory method to create a Criteria using the provided key
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Criteria and(String key) {
|
||||
return new Criteria(this.criteriaChain, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using equality
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria is(Object o) {
|
||||
if (isValue != NOT_SET) {
|
||||
throw new InvalidDocumentStoreApiUsageException(
|
||||
"Multiple 'is' values declared. You need to use 'and' with multiple criteria");
|
||||
}
|
||||
if (this.criteria.size() > 0 && "$not".equals(this.criteria.keySet().toArray()[this.criteria.size() - 1])) {
|
||||
throw new InvalidDocumentStoreApiUsageException(
|
||||
"Invalid query: 'not' can't be used with 'is' - use 'ne' instead.");
|
||||
}
|
||||
this.isValue = o;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $ne operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria ne(Object o) {
|
||||
criteria.put("$ne", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $lt operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria lt(Object o) {
|
||||
criteria.put("$lt", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $lte operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria lte(Object o) {
|
||||
criteria.put("$lte", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $gt operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria gt(Object o) {
|
||||
criteria.put("$gt", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $gte operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria gte(Object o) {
|
||||
criteria.put("$gte", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $in operator
|
||||
*
|
||||
* @param o the values to match against
|
||||
* @return
|
||||
*/
|
||||
public Criteria in(Object... o) {
|
||||
if (o.length > 1 && o[1] instanceof Collection) {
|
||||
throw new InvalidDocumentStoreApiUsageException("You can only pass in one argument of type " + o[1].getClass().getName());
|
||||
public Criteria(String key) {
|
||||
this.criteriaChain = new ArrayList<Criteria>();
|
||||
this.criteriaChain.add(this);
|
||||
this.key = key;
|
||||
}
|
||||
criteria.put("$in", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $in operator
|
||||
*
|
||||
* @param c the collection containing the values to match against
|
||||
* @return
|
||||
*/
|
||||
public Criteria in(Collection<?> c) {
|
||||
System.out.println(c.getClass());
|
||||
criteria.put("$in", c.toArray());
|
||||
return this;
|
||||
}
|
||||
protected Criteria(List<Criteria> criteriaChain, String key) {
|
||||
this.criteriaChain = criteriaChain;
|
||||
this.criteriaChain.add(this);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $nin operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria nin(Object... o) {
|
||||
criteria.put("$nin", o);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Static factory method to create a Criteria using the provided key
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static Criteria where(String key) {
|
||||
return new Criteria(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $mod operator
|
||||
*
|
||||
* @param value
|
||||
* @param remainder
|
||||
* @return
|
||||
*/
|
||||
public Criteria mod(Number value, Number remainder) {
|
||||
List<Object> l = new ArrayList<Object>();
|
||||
l.add(value);
|
||||
l.add(remainder);
|
||||
criteria.put("$mod", l);
|
||||
return this;
|
||||
}
|
||||
public static Criteria whereId() {
|
||||
return new Criteria("id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $all operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria all(Object... o) {
|
||||
criteria.put("$all", o);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Static factory method to create a Criteria using the provided key
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Criteria and(String key) {
|
||||
return new Criteria(this.criteriaChain, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $size operator
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public Criteria size(int s) {
|
||||
criteria.put("$size", s);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using equality
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria is(Object o) {
|
||||
if (isValue != NOT_SET) {
|
||||
throw new InvalidDocumentStoreApiUsageException(
|
||||
"Multiple 'is' values declared. You need to use 'and' with multiple criteria");
|
||||
}
|
||||
if (this.criteria.size() > 0 && "$not".equals(this.criteria.keySet().toArray()[this.criteria.size() - 1])) {
|
||||
throw new InvalidDocumentStoreApiUsageException(
|
||||
"Invalid query: 'not' can't be used with 'is' - use 'ne' instead.");
|
||||
}
|
||||
this.isValue = o;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $exists operator
|
||||
*
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public Criteria exists(boolean b) {
|
||||
criteria.put("$exists", b);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $ne operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria ne(Object o) {
|
||||
criteria.put("$ne", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $type operator
|
||||
*
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
public Criteria type(int t) {
|
||||
criteria.put("$type", t);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $lt operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria lt(Object o) {
|
||||
criteria.put("$lt", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $not meta operator which affects the clause directly following
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Criteria not() {
|
||||
criteria.put("$not", null);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $lte operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria lte(Object o) {
|
||||
criteria.put("$lte", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using a $regex
|
||||
*
|
||||
* @param re
|
||||
* @return
|
||||
*/
|
||||
public Criteria regex(String re) {
|
||||
criteria.put("$regex", re);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $gt operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria gt(Object o) {
|
||||
criteria.put("$gt", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $within $center operation
|
||||
*
|
||||
* @param circle
|
||||
* must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
public Criteria withinCenter(Circle circle) {
|
||||
Assert.notNull(circle);
|
||||
LinkedList<Object> list = new LinkedList<Object>();
|
||||
list.addLast(circle.getCenter().asArray());
|
||||
list.add(circle.getRadius());
|
||||
criteria.put("$within", new BasicDBObject("$center", list));
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $gte operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria gte(Object o) {
|
||||
criteria.put("$gte", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $within $center operation. This is only available for Mongo 1.7 and higher.
|
||||
*
|
||||
* @param circle
|
||||
* must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
public Criteria withinCenterSphere(Circle circle) {
|
||||
Assert.notNull(circle);
|
||||
LinkedList<Object> list = new LinkedList<Object>();
|
||||
list.addLast(circle.getCenter().asArray());
|
||||
list.add(circle.getRadius());
|
||||
criteria.put("$within", new BasicDBObject("$centerSphere", list));
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $in operator
|
||||
*
|
||||
* @param o
|
||||
* the values to match against
|
||||
* @return
|
||||
*/
|
||||
public Criteria in(Object... o) {
|
||||
if (o.length > 1 && o[1] instanceof Collection) {
|
||||
throw new InvalidDocumentStoreApiUsageException("You can only pass in one argument of type "
|
||||
+ o[1].getClass().getName());
|
||||
}
|
||||
criteria.put("$in", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $within $box operation
|
||||
*
|
||||
* @param box
|
||||
* @return
|
||||
*/
|
||||
public Criteria withinBox(Box box) {
|
||||
Assert.notNull(box);
|
||||
LinkedList<double[]> list = new LinkedList<double[]>();
|
||||
list.addLast(box.getLowerLeft().asArray());
|
||||
list.addLast(box.getUpperRight().asArray());
|
||||
criteria.put("$within", new BasicDBObject("$box", list));
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $in operator
|
||||
*
|
||||
* @param c
|
||||
* the collection containing the values to match against
|
||||
* @return
|
||||
*/
|
||||
public Criteria in(Collection<?> c) {
|
||||
System.out.println(c.getClass());
|
||||
criteria.put("$in", c.toArray());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $near operation
|
||||
*
|
||||
* @param point
|
||||
* must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
public Criteria near(Point point) {
|
||||
Assert.notNull(point);
|
||||
criteria.put("$near", point.asArray());
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $nin operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria nin(Object... o) {
|
||||
criteria.put("$nin", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $nearSphere operation. This is only available for Mongo 1.7 and higher.
|
||||
*
|
||||
* @param point
|
||||
* must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
public Criteria nearSphere(Point point) {
|
||||
Assert.notNull(point);
|
||||
criteria.put("$nearSphere", point.asArray());
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $mod operator
|
||||
*
|
||||
* @param value
|
||||
* @param remainder
|
||||
* @return
|
||||
*/
|
||||
public Criteria mod(Number value, Number remainder) {
|
||||
List<Object> l = new ArrayList<Object>();
|
||||
l.add(value);
|
||||
l.add(remainder);
|
||||
criteria.put("$mod", l);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatical criterion using a $maxDistance operation, for use with $near
|
||||
*
|
||||
* @param maxDistance
|
||||
* @return
|
||||
*/
|
||||
public Criteria maxDistance(double maxDistance) {
|
||||
criteria.put("$maxDistance", maxDistance);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $all operator
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public Criteria all(Object... o) {
|
||||
criteria.put("$all", o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $elemMatch operator
|
||||
*
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
public Criteria elemMatch(Criteria c) {
|
||||
criteria.put("$elemMatch", c.getCriteriaObject());
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $size operator
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public Criteria size(int s) {
|
||||
criteria.put("$size", s);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an or query using the $or operator for all of the provided queries
|
||||
*
|
||||
* @param queries
|
||||
*/
|
||||
public void or(List<Query> queries) {
|
||||
criteria.put("$or", queries);
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $exists operator
|
||||
*
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public Criteria exists(boolean b) {
|
||||
criteria.put("$exists", b);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $type operator
|
||||
*
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
public Criteria type(int t) {
|
||||
criteria.put("$type", t);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.datastore.document.mongodb.query.Criteria#
|
||||
* getCriteriaObject(java.lang.String)
|
||||
*/
|
||||
public DBObject getCriteriaObject() {
|
||||
if (this.criteriaChain.size() == 1) {
|
||||
return criteriaChain.get(0).getSingleCriteriaObject();
|
||||
} else {
|
||||
DBObject criteriaObject = new BasicDBObject();
|
||||
for (Criteria c : this.criteriaChain) {
|
||||
criteriaObject.putAll(c.getSingleCriteriaObject());
|
||||
}
|
||||
return criteriaObject;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using the $not meta operator which affects the clause directly following
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Criteria not() {
|
||||
criteria.put("$not", null);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected DBObject getSingleCriteriaObject() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
boolean not = false;
|
||||
for (String k : this.criteria.keySet()) {
|
||||
if (not) {
|
||||
DBObject notDbo = new BasicDBObject();
|
||||
notDbo.put(k, this.criteria.get(k));
|
||||
dbo.put("$not", notDbo);
|
||||
not = false;
|
||||
} else {
|
||||
if ("$not".equals(k)) {
|
||||
not = true;
|
||||
} else {
|
||||
dbo.put(k, this.criteria.get(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
DBObject queryCriteria = new BasicDBObject();
|
||||
if (isValue != NOT_SET) {
|
||||
queryCriteria.put(this.key, this.isValue);
|
||||
queryCriteria.putAll(dbo);
|
||||
} else {
|
||||
queryCriteria.put(this.key, dbo);
|
||||
}
|
||||
return queryCriteria;
|
||||
}
|
||||
/**
|
||||
* Creates a criterion using a $regex
|
||||
*
|
||||
* @param re
|
||||
* @return
|
||||
*/
|
||||
public Criteria regex(String re) {
|
||||
criteria.put("$regex", re);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $within $center operation
|
||||
*
|
||||
* @param circle
|
||||
* must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
public Criteria withinCenter(Circle circle) {
|
||||
Assert.notNull(circle);
|
||||
LinkedList<Object> list = new LinkedList<Object>();
|
||||
list.addLast(circle.getCenter().asArray());
|
||||
list.add(circle.getRadius());
|
||||
criteria.put("$within", new BasicDBObject("$center", list));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $within $center operation. This is only available for Mongo 1.7 and higher.
|
||||
*
|
||||
* @param circle
|
||||
* must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
public Criteria withinCenterSphere(Circle circle) {
|
||||
Assert.notNull(circle);
|
||||
LinkedList<Object> list = new LinkedList<Object>();
|
||||
list.addLast(circle.getCenter().asArray());
|
||||
list.add(circle.getRadius());
|
||||
criteria.put("$within", new BasicDBObject("$centerSphere", list));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $within $box operation
|
||||
*
|
||||
* @param box
|
||||
* @return
|
||||
*/
|
||||
public Criteria withinBox(Box box) {
|
||||
Assert.notNull(box);
|
||||
LinkedList<double[]> list = new LinkedList<double[]>();
|
||||
list.addLast(box.getLowerLeft().asArray());
|
||||
list.addLast(box.getUpperRight().asArray());
|
||||
criteria.put("$within", new BasicDBObject("$box", list));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $near operation
|
||||
*
|
||||
* @param point
|
||||
* must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
public Criteria near(Point point) {
|
||||
Assert.notNull(point);
|
||||
criteria.put("$near", point.asArray());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $nearSphere operation. This is only available for Mongo 1.7 and higher.
|
||||
*
|
||||
* @param point
|
||||
* must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
public Criteria nearSphere(Point point) {
|
||||
Assert.notNull(point);
|
||||
criteria.put("$nearSphere", point.asArray());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatical criterion using a $maxDistance operation, for use with $near
|
||||
*
|
||||
* @param maxDistance
|
||||
* @return
|
||||
*/
|
||||
public Criteria maxDistance(double maxDistance) {
|
||||
criteria.put("$maxDistance", maxDistance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $elemMatch operator
|
||||
*
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
public Criteria elemMatch(Criteria c) {
|
||||
criteria.put("$elemMatch", c.getCriteriaObject());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an or query using the $or operator for all of the provided queries
|
||||
*
|
||||
* @param queries
|
||||
*/
|
||||
public void or(List<Query> queries) {
|
||||
criteria.put("$or", queries);
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.datastore.document.mongodb.query.Criteria#
|
||||
* getCriteriaObject(java.lang.String)
|
||||
*/
|
||||
public DBObject getCriteriaObject() {
|
||||
if (this.criteriaChain.size() == 1) {
|
||||
return criteriaChain.get(0).getSingleCriteriaObject();
|
||||
} else {
|
||||
DBObject criteriaObject = new BasicDBObject();
|
||||
for (Criteria c : this.criteriaChain) {
|
||||
criteriaObject.putAll(c.getSingleCriteriaObject());
|
||||
}
|
||||
return criteriaObject;
|
||||
}
|
||||
}
|
||||
|
||||
protected DBObject getSingleCriteriaObject() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
boolean not = false;
|
||||
for (String k : this.criteria.keySet()) {
|
||||
if (not) {
|
||||
DBObject notDbo = new BasicDBObject();
|
||||
notDbo.put(k, this.criteria.get(k));
|
||||
dbo.put("$not", notDbo);
|
||||
not = false;
|
||||
} else {
|
||||
if ("$not".equals(k)) {
|
||||
not = true;
|
||||
} else {
|
||||
dbo.put(k, this.criteria.get(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
DBObject queryCriteria = new BasicDBObject();
|
||||
if (isValue != NOT_SET) {
|
||||
queryCriteria.put(this.key, this.isValue);
|
||||
queryCriteria.putAll(dbo);
|
||||
} else {
|
||||
queryCriteria.put(this.key, dbo);
|
||||
}
|
||||
return queryCriteria;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ import com.mongodb.DBObject;
|
||||
|
||||
public interface CriteriaDefinition {
|
||||
|
||||
DBObject getCriteriaObject();
|
||||
DBObject getCriteriaObject();
|
||||
|
||||
}
|
||||
@@ -21,41 +21,40 @@ import java.util.Map;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
|
||||
public class Field {
|
||||
|
||||
private Map<String, Integer> criteria = new HashMap<String, Integer>();
|
||||
private Map<String, Integer> criteria = new HashMap<String, Integer>();
|
||||
|
||||
private Map<String, Object> slices = new HashMap<String, Object>();
|
||||
private Map<String, Object> slices = new HashMap<String, Object>();
|
||||
|
||||
public Field include(String key) {
|
||||
criteria.put(key, Integer.valueOf(1));
|
||||
return this;
|
||||
}
|
||||
public Field include(String key) {
|
||||
criteria.put(key, Integer.valueOf(1));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Field exclude(String key) {
|
||||
criteria.put(key, Integer.valueOf(0));
|
||||
return this;
|
||||
}
|
||||
public Field exclude(String key) {
|
||||
criteria.put(key, Integer.valueOf(0));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Field slice(String key, int size) {
|
||||
slices.put(key, Integer.valueOf(size));
|
||||
return this;
|
||||
}
|
||||
public Field slice(String key, int size) {
|
||||
slices.put(key, Integer.valueOf(size));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Field slice(String key, int offset, int size) {
|
||||
slices.put(key, new Integer[]{Integer.valueOf(offset), Integer.valueOf(size)});
|
||||
return this;
|
||||
}
|
||||
public Field slice(String key, int offset, int size) {
|
||||
slices.put(key, new Integer[] { Integer.valueOf(offset), Integer.valueOf(size) });
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getFieldsObject() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : criteria.keySet()) {
|
||||
dbo.put(k, (criteria.get(k)));
|
||||
}
|
||||
for (String k : slices.keySet()) {
|
||||
dbo.put(k, new BasicDBObject("$slice", (slices.get(k))));
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
public DBObject getFieldsObject() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : criteria.keySet()) {
|
||||
dbo.put(k, (criteria.get(k)));
|
||||
}
|
||||
for (String k : slices.keySet()) {
|
||||
dbo.put(k, new BasicDBObject("$slice", (slices.get(k))));
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,74 +20,73 @@ import org.springframework.data.document.mongodb.index.IndexDefinition;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
|
||||
public class GeospatialIndex implements IndexDefinition {
|
||||
|
||||
private String keyField;
|
||||
private String keyField;
|
||||
|
||||
private String name;
|
||||
private String name;
|
||||
|
||||
private Integer min = null;
|
||||
private Integer min = null;
|
||||
|
||||
private Integer max = null;
|
||||
|
||||
private Integer bits = null;
|
||||
private Integer max = null;
|
||||
|
||||
public GeospatialIndex(String key) {
|
||||
keyField = key;
|
||||
}
|
||||
private Integer bits = null;
|
||||
|
||||
public GeospatialIndex named(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
public GeospatialIndex(String key) {
|
||||
keyField = key;
|
||||
}
|
||||
|
||||
public GeospatialIndex withMin(int min) {
|
||||
this.min = Integer.valueOf(min);
|
||||
return this;
|
||||
}
|
||||
public GeospatialIndex named(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeospatialIndex withMax(int max) {
|
||||
this.max = Integer.valueOf(max);
|
||||
return this;
|
||||
}
|
||||
public GeospatialIndex withMin(int min) {
|
||||
this.min = Integer.valueOf(min);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeospatialIndex withBits(int bits) {
|
||||
this.bits = Integer.valueOf(bits);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getIndexKeys() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
dbo.put(keyField, "2d");
|
||||
return dbo;
|
||||
}
|
||||
public GeospatialIndex withMax(int max) {
|
||||
this.max = Integer.valueOf(max);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getIndexOptions() {
|
||||
if (name == null && min == null && max == null) {
|
||||
return null;
|
||||
}
|
||||
DBObject dbo = new BasicDBObject();
|
||||
if (name != null) {
|
||||
dbo.put("name", name);
|
||||
}
|
||||
if (min != null) {
|
||||
dbo.put("min", min);
|
||||
}
|
||||
if (max != null) {
|
||||
dbo.put("max", max);
|
||||
}
|
||||
if (bits != null) {
|
||||
dbo.put("bits", bits);
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
public GeospatialIndex withBits(int bits) {
|
||||
this.bits = Integer.valueOf(bits);
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Geo index: %s - Options: %s", getIndexKeys(), getIndexOptions());
|
||||
}
|
||||
public DBObject getIndexKeys() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
dbo.put(keyField, "2d");
|
||||
return dbo;
|
||||
}
|
||||
|
||||
public DBObject getIndexOptions() {
|
||||
if (name == null && min == null && max == null) {
|
||||
return null;
|
||||
}
|
||||
DBObject dbo = new BasicDBObject();
|
||||
if (name != null) {
|
||||
dbo.put("name", name);
|
||||
}
|
||||
if (min != null) {
|
||||
dbo.put("min", min);
|
||||
}
|
||||
if (max != null) {
|
||||
dbo.put("max", max);
|
||||
}
|
||||
if (bits != null) {
|
||||
dbo.put("bits", bits);
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Geo index: %s - Options: %s", getIndexKeys(), getIndexOptions());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,88 +23,86 @@ import org.springframework.data.document.mongodb.index.IndexDefinition;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
|
||||
public class Index implements IndexDefinition {
|
||||
|
||||
public enum Duplicates {
|
||||
RETAIN,
|
||||
DROP
|
||||
}
|
||||
public enum Duplicates {
|
||||
RETAIN, DROP
|
||||
}
|
||||
|
||||
private Map<String, Order> fieldSpec = new HashMap<String, Order>();
|
||||
private Map<String, Order> fieldSpec = new HashMap<String, Order>();
|
||||
|
||||
private String name;
|
||||
private String name;
|
||||
|
||||
private boolean unique = false;
|
||||
private boolean unique = false;
|
||||
|
||||
private boolean dropDuplicates = false;
|
||||
|
||||
private boolean sparse = false;
|
||||
private boolean dropDuplicates = false;
|
||||
|
||||
public Index() {
|
||||
}
|
||||
private boolean sparse = false;
|
||||
|
||||
public Index(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
}
|
||||
public Index() {
|
||||
}
|
||||
|
||||
public Index on(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
return this;
|
||||
}
|
||||
public Index(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
}
|
||||
|
||||
public Index named(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
public Index on(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Index unique() {
|
||||
this.unique = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Index sparse() {
|
||||
this.sparse = true;
|
||||
return this;
|
||||
}
|
||||
public Index named(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Index unique(Duplicates duplicates) {
|
||||
if (duplicates == Duplicates.DROP) {
|
||||
this.dropDuplicates = true;
|
||||
}
|
||||
return unique();
|
||||
}
|
||||
public Index unique() {
|
||||
this.unique = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getIndexKeys() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : fieldSpec.keySet()) {
|
||||
dbo.put(k, (fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1));
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
public Index sparse() {
|
||||
this.sparse = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getIndexOptions() {
|
||||
if (name == null && !unique) {
|
||||
return null;
|
||||
}
|
||||
DBObject dbo = new BasicDBObject();
|
||||
if (name != null) {
|
||||
dbo.put("name", name);
|
||||
}
|
||||
if (unique) {
|
||||
dbo.put("unique", true);
|
||||
}
|
||||
if (dropDuplicates) {
|
||||
dbo.put("dropDups", true);
|
||||
}
|
||||
if (sparse) {
|
||||
dbo.put("sparse", true);
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Index: %s - Options: %s", getIndexKeys(), getIndexOptions());
|
||||
}
|
||||
public Index unique(Duplicates duplicates) {
|
||||
if (duplicates == Duplicates.DROP) {
|
||||
this.dropDuplicates = true;
|
||||
}
|
||||
return unique();
|
||||
}
|
||||
|
||||
public DBObject getIndexKeys() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : fieldSpec.keySet()) {
|
||||
dbo.put(k, (fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1));
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
|
||||
public DBObject getIndexOptions() {
|
||||
if (name == null && !unique) {
|
||||
return null;
|
||||
}
|
||||
DBObject dbo = new BasicDBObject();
|
||||
if (name != null) {
|
||||
dbo.put("name", name);
|
||||
}
|
||||
if (unique) {
|
||||
dbo.put("unique", true);
|
||||
}
|
||||
if (dropDuplicates) {
|
||||
dbo.put("dropDups", true);
|
||||
}
|
||||
if (sparse) {
|
||||
dbo.put("sparse", true);
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Index: %s - Options: %s", getIndexKeys(), getIndexOptions());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ package org.springframework.data.document.mongodb.query;
|
||||
|
||||
/**
|
||||
* An enum that specifies the ordering for sort or index specifications
|
||||
*
|
||||
*
|
||||
* @author trisberg
|
||||
*/
|
||||
public enum Order {
|
||||
ASCENDING, DESCENDING
|
||||
ASCENDING, DESCENDING
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class Query {
|
||||
|
||||
/**
|
||||
* Static factory method to create a Query using the provided criteria
|
||||
*
|
||||
*
|
||||
* @param critera
|
||||
* @return
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A helper class to encapsulate any modifications of a Query object before it gets submitted to the database.
|
||||
*
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@@ -41,7 +41,7 @@ public class QueryMapper {
|
||||
|
||||
/**
|
||||
* Creates a new {@link QueryMapper} with the given {@link MongoConverter}.
|
||||
*
|
||||
*
|
||||
* @param converter
|
||||
*/
|
||||
public QueryMapper(MongoConverter converter) {
|
||||
@@ -52,7 +52,7 @@ public class QueryMapper {
|
||||
/**
|
||||
* Replaces the property keys used in the given {@link DBObject} with the appropriate keys by using the
|
||||
* {@link PersistentEntity} metadata.
|
||||
*
|
||||
*
|
||||
* @param query
|
||||
* @param entity
|
||||
* @return
|
||||
|
||||
@@ -21,29 +21,28 @@ import java.util.Map;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
|
||||
public class Sort {
|
||||
|
||||
private Map<String, Order> fieldSpec = new HashMap<String, Order>();
|
||||
private Map<String, Order> fieldSpec = new HashMap<String, Order>();
|
||||
|
||||
public Sort() {
|
||||
}
|
||||
public Sort() {
|
||||
}
|
||||
|
||||
public Sort(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
}
|
||||
public Sort(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
}
|
||||
|
||||
public Sort on(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
return this;
|
||||
}
|
||||
public Sort on(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getSortObject() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : fieldSpec.keySet()) {
|
||||
dbo.put(k, (fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1));
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
public DBObject getSortObject() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : fieldSpec.keySet()) {
|
||||
dbo.put(k, (fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1));
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Static factory method to create an Update using the provided key
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@@ -42,7 +42,7 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Update using the $set update modifier
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
@@ -54,7 +54,7 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Update using the $unset update modifier
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@@ -65,7 +65,7 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Update using the $inc update modifier
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param inc
|
||||
* @return
|
||||
@@ -77,7 +77,7 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Update using the $push update modifier
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
@@ -89,7 +89,7 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Update using the $pushAll update modifier
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param values
|
||||
* @return
|
||||
@@ -107,7 +107,7 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Update using the $addToSet update modifier
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
@@ -119,20 +119,19 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Update using the $pop update modifier
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param pos
|
||||
* @return
|
||||
*/
|
||||
public Update pop(String key, Position pos) {
|
||||
addMultiFieldOperation("$pop", key,
|
||||
(pos == Position.FIRST ? -1 : 1));
|
||||
addMultiFieldOperation("$pop", key, (pos == Position.FIRST ? -1 : 1));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update using the $pull update modifier
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
@@ -144,7 +143,7 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Update using the $pullAll update modifier
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param values
|
||||
* @return
|
||||
@@ -162,7 +161,7 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Update using the $rename update modifier
|
||||
*
|
||||
*
|
||||
* @param oldName
|
||||
* @param newName
|
||||
* @return
|
||||
@@ -181,8 +180,7 @@ public class Update {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void addMultiFieldOperation(String operator, String key,
|
||||
Object value) {
|
||||
protected void addMultiFieldOperation(String operator, String key, Object value) {
|
||||
Object existingValue = this.modifierOps.get(operator);
|
||||
LinkedHashMap<String, Object> keyValueMap;
|
||||
if (existingValue == null) {
|
||||
@@ -192,8 +190,8 @@ public class Update {
|
||||
if (existingValue instanceof LinkedHashMap) {
|
||||
keyValueMap = (LinkedHashMap<String, Object>) existingValue;
|
||||
} else {
|
||||
throw new InvalidDataAccessApiUsageException("Modifier Operations should be a LinkedHashMap but was " +
|
||||
existingValue.getClass());
|
||||
throw new InvalidDataAccessApiUsageException("Modifier Operations should be a LinkedHashMap but was "
|
||||
+ existingValue.getClass());
|
||||
}
|
||||
}
|
||||
keyValueMap.put(key, value);
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
* MongoDB specific query and update support.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb.query;
|
||||
|
||||
|
||||
@@ -34,165 +34,165 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class for {@link RepositoryQuery} implementations for Mongo.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
private final MongoQueryMethod method;
|
||||
private final MongoTemplate template;
|
||||
private final MongoQueryMethod method;
|
||||
private final MongoTemplate template;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AbstractMongoQuery} from the given {@link MongoQueryMethod} and {@link MongoTemplate}.
|
||||
*
|
||||
* @param method
|
||||
* @param template
|
||||
*/
|
||||
public AbstractMongoQuery(MongoQueryMethod method, MongoTemplate template) {
|
||||
/**
|
||||
* Creates a new {@link AbstractMongoQuery} from the given {@link MongoQueryMethod} and {@link MongoTemplate}.
|
||||
*
|
||||
* @param method
|
||||
* @param template
|
||||
*/
|
||||
public AbstractMongoQuery(MongoQueryMethod method, MongoTemplate template) {
|
||||
|
||||
Assert.notNull(template);
|
||||
Assert.notNull(method);
|
||||
Assert.notNull(template);
|
||||
Assert.notNull(method);
|
||||
|
||||
this.method = method;
|
||||
this.template = template;
|
||||
}
|
||||
this.method = method;
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
|
||||
*/
|
||||
public MongoQueryMethod getQueryMethod() {
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
|
||||
*/
|
||||
public MongoQueryMethod getQueryMethod() {
|
||||
|
||||
return method;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java .lang.Object[])
|
||||
*/
|
||||
public Object execute(Object[] parameters) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java .lang.Object[])
|
||||
*/
|
||||
public Object execute(Object[] parameters) {
|
||||
|
||||
ParameterAccessor accessor = new ParametersParameterAccessor(method.getParameters(), parameters);
|
||||
Query query = createQuery(new ConvertingParameterAccessor(template.getConverter(), accessor));
|
||||
ParameterAccessor accessor = new ParametersParameterAccessor(method.getParameters(), parameters);
|
||||
Query query = createQuery(new ConvertingParameterAccessor(template.getConverter(), accessor));
|
||||
|
||||
switch (method.getType()) {
|
||||
case COLLECTION:
|
||||
return new CollectionExecution().execute(query);
|
||||
case PAGING:
|
||||
return new PagedExecution(accessor.getPageable()).execute(query);
|
||||
default:
|
||||
return new SingleEntityExecution().execute(query);
|
||||
}
|
||||
}
|
||||
switch (method.getType()) {
|
||||
case COLLECTION:
|
||||
return new CollectionExecution().execute(query);
|
||||
case PAGING:
|
||||
return new PagedExecution(accessor.getPageable()).execute(query);
|
||||
default:
|
||||
return new SingleEntityExecution().execute(query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link Query} instance using the given {@link ParameterAccessor}
|
||||
*
|
||||
* @param accessor
|
||||
* @param converter
|
||||
* @return
|
||||
*/
|
||||
protected abstract Query createQuery(ConvertingParameterAccessor accessor);
|
||||
/**
|
||||
* Create a {@link Query} instance using the given {@link ParameterAccessor}
|
||||
*
|
||||
* @param accessor
|
||||
* @param converter
|
||||
* @return
|
||||
*/
|
||||
protected abstract Query createQuery(ConvertingParameterAccessor accessor);
|
||||
|
||||
private abstract class Execution {
|
||||
private abstract class Execution {
|
||||
|
||||
abstract Object execute(Query query);
|
||||
abstract Object execute(Query query);
|
||||
|
||||
protected List<?> readCollection(Query query) {
|
||||
protected List<?> readCollection(Query query) {
|
||||
|
||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
||||
|
||||
String collectionName = metadata.getCollectionName();
|
||||
return template.find(collectionName, query, metadata.getJavaType());
|
||||
}
|
||||
}
|
||||
String collectionName = metadata.getCollectionName();
|
||||
return template.find(collectionName, query, metadata.getJavaType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Execution} for collection returning queries.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class CollectionExecution extends Execution {
|
||||
/**
|
||||
* {@link Execution} for collection returning queries.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class CollectionExecution extends Execution {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoQuery.Execution #execute(com.mongodb.DBObject)
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Query query) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoQuery.Execution #execute(com.mongodb.DBObject)
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Query query) {
|
||||
|
||||
return readCollection(query);
|
||||
}
|
||||
}
|
||||
return readCollection(query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Execution} for pagination queries.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class PagedExecution extends Execution {
|
||||
/**
|
||||
* {@link Execution} for pagination queries.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class PagedExecution extends Execution {
|
||||
|
||||
private final Pageable pageable;
|
||||
private final Pageable pageable;
|
||||
|
||||
/**
|
||||
* Creates a new {@link PagedExecution}.
|
||||
*
|
||||
* @param pageable
|
||||
*/
|
||||
public PagedExecution(Pageable pageable) {
|
||||
/**
|
||||
* Creates a new {@link PagedExecution}.
|
||||
*
|
||||
* @param pageable
|
||||
*/
|
||||
public PagedExecution(Pageable pageable) {
|
||||
|
||||
Assert.notNull(pageable);
|
||||
this.pageable = pageable;
|
||||
}
|
||||
Assert.notNull(pageable);
|
||||
this.pageable = pageable;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoQuery.Execution #execute(com.mongodb.DBObject)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
Object execute(Query query) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoQuery.Execution #execute(com.mongodb.DBObject)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
Object execute(Query query) {
|
||||
|
||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
||||
int count = getCollectionCursor(metadata.getCollectionName(), query.getQueryObject()).count();
|
||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
||||
int count = getCollectionCursor(metadata.getCollectionName(), query.getQueryObject()).count();
|
||||
|
||||
List<?> result = template.find(metadata.getCollectionName(), applyPagination(query, pageable),
|
||||
metadata.getJavaType());
|
||||
List<?> result = template.find(metadata.getCollectionName(), applyPagination(query, pageable),
|
||||
metadata.getJavaType());
|
||||
|
||||
return new PageImpl(result, pageable, count);
|
||||
}
|
||||
return new PageImpl(result, pageable, count);
|
||||
}
|
||||
|
||||
private DBCursor getCollectionCursor(String collectionName, final DBObject query) {
|
||||
private DBCursor getCollectionCursor(String collectionName, final DBObject query) {
|
||||
|
||||
return template.execute(collectionName, new CollectionCallback<DBCursor>() {
|
||||
return template.execute(collectionName, new CollectionCallback<DBCursor>() {
|
||||
|
||||
public DBCursor doInCollection(DBCollection collection) {
|
||||
public DBCursor doInCollection(DBCollection collection) {
|
||||
|
||||
return collection.find(query);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return collection.find(query);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Execution} to return a single entity.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class SingleEntityExecution extends Execution {
|
||||
/**
|
||||
* {@link Execution} to return a single entity.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class SingleEntityExecution extends Execution {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoQuery.Execution #execute(com.mongodb.DBObject)
|
||||
*/
|
||||
@Override
|
||||
Object execute(Query query) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoQuery.Execution #execute(com.mongodb.DBObject)
|
||||
*/
|
||||
@Override
|
||||
Object execute(Query query) {
|
||||
|
||||
List<?> result = readCollection(query);
|
||||
return result.isEmpty() ? null : result.get(0);
|
||||
}
|
||||
}
|
||||
List<?> result = readCollection(query);
|
||||
return result.isEmpty() ? null : result.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,160 +28,160 @@ import org.springframework.data.repository.query.ParameterAccessor;
|
||||
|
||||
/**
|
||||
* Custom {@link ParameterAccessor} that uses a {@link MongoWriter} to serialize parameters into Mongo format.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class ConvertingParameterAccessor implements ParameterAccessor {
|
||||
|
||||
private final MongoWriter<Object> writer;
|
||||
private final ParameterAccessor delegate;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConvertingParameterAccessor} with the given {@link MongoWriter} and delegate.
|
||||
*
|
||||
* @param writer
|
||||
*/
|
||||
public ConvertingParameterAccessor(MongoWriter<Object> writer, ParameterAccessor delegate) {
|
||||
this.writer = writer;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
private final MongoWriter<Object> writer;
|
||||
private final ParameterAccessor delegate;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<Object> iterator() {
|
||||
return new ConvertingIterator(delegate.iterator());
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link ConvertingParameterAccessor} with the given {@link MongoWriter} and delegate.
|
||||
*
|
||||
* @param writer
|
||||
*/
|
||||
public ConvertingParameterAccessor(MongoWriter<Object> writer, ParameterAccessor delegate) {
|
||||
this.writer = writer;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.query.ParameterAccessor#getPageable()
|
||||
*/
|
||||
public Pageable getPageable() {
|
||||
return delegate.getPageable();
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<Object> iterator() {
|
||||
return new ConvertingIterator(delegate.iterator());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.query.ParameterAccessor#getSort()
|
||||
*/
|
||||
public Sort getSort() {
|
||||
return delegate.getSort();
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.query.ParameterAccessor#getPageable()
|
||||
*/
|
||||
public Pageable getPageable() {
|
||||
return delegate.getPageable();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.ParameterAccessor#getBindableParameter(int)
|
||||
*/
|
||||
public Object getBindableValue(int index) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.query.ParameterAccessor#getSort()
|
||||
*/
|
||||
public Sort getSort() {
|
||||
return delegate.getSort();
|
||||
}
|
||||
|
||||
return getConvertedValue(delegate.getBindableValue(index));
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.ParameterAccessor#getBindableParameter(int)
|
||||
*/
|
||||
public Object getBindableValue(int index) {
|
||||
|
||||
/**
|
||||
* Converts the given value with the underlying {@link MongoWriter}.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private Object getConvertedValue(Object value) {
|
||||
|
||||
DBObject result = new BasicDBObject();
|
||||
writer.write(new ValueHolder(value), result);
|
||||
return ((DBObject) result.get("value")).get("value");
|
||||
}
|
||||
return getConvertedValue(delegate.getBindableValue(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link Iterator} to convert items before returning them.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class ConvertingIterator implements PotentiallyConvertingIterator {
|
||||
/**
|
||||
* Converts the given value with the underlying {@link MongoWriter}.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private Object getConvertedValue(Object value) {
|
||||
|
||||
private final Iterator<Object> delegate;
|
||||
DBObject result = new BasicDBObject();
|
||||
writer.write(new ValueHolder(value), result);
|
||||
return ((DBObject) result.get("value")).get("value");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConvertingIterator} for the given delegate.
|
||||
*
|
||||
* @param delegate
|
||||
*/
|
||||
public ConvertingIterator(Iterator<Object> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
/**
|
||||
* Custom {@link Iterator} to convert items before returning them.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class ConvertingIterator implements PotentiallyConvertingIterator {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.Iterator#hasNext()
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return delegate.hasNext();
|
||||
}
|
||||
private final Iterator<Object> delegate;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.Iterator#next()
|
||||
*/
|
||||
public Object next() {
|
||||
/**
|
||||
* Creates a new {@link ConvertingIterator} for the given delegate.
|
||||
*
|
||||
* @param delegate
|
||||
*/
|
||||
public ConvertingIterator(Iterator<Object> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
return delegate.next();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.repository.ConvertingParameterAccessor.PotentiallConvertingIterator#nextConverted()
|
||||
*/
|
||||
public Object nextConverted() {
|
||||
|
||||
return getConvertedValue(next());
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.Iterator#hasNext()
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return delegate.hasNext();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.Iterator#remove()
|
||||
*/
|
||||
public void remove() {
|
||||
delegate.remove();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.Iterator#next()
|
||||
*/
|
||||
public Object next() {
|
||||
|
||||
/**
|
||||
* Simple value holder class to allow conversion and accessing the converted value in a deterministic way.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class ValueHolder {
|
||||
return delegate.next();
|
||||
}
|
||||
|
||||
private Map<String, Object> value = new HashMap<String, Object>();
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.repository.ConvertingParameterAccessor.PotentiallConvertingIterator#nextConverted()
|
||||
*/
|
||||
public Object nextConverted() {
|
||||
|
||||
public ValueHolder(Object value) {
|
||||
return getConvertedValue(next());
|
||||
}
|
||||
|
||||
this.value.put("value", value);
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.Iterator#remove()
|
||||
*/
|
||||
public void remove() {
|
||||
delegate.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Map<String, Object> getValue() {
|
||||
/**
|
||||
* Simple value holder class to allow conversion and accessing the converted value in a deterministic way.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class ValueHolder {
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
private Map<String, Object> value = new HashMap<String, Object>();
|
||||
|
||||
/**
|
||||
* Custom {@link Iterator} that adds a method to access elements in a converted manner.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface PotentiallyConvertingIterator extends Iterator<Object> {
|
||||
|
||||
/**
|
||||
* Returns the next element which has already been converted.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Object nextConverted();
|
||||
}
|
||||
public ValueHolder(Object value) {
|
||||
|
||||
this.value.put("value", value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Map<String, Object> getValue() {
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link Iterator} that adds a method to access elements in a converted manner.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface PotentiallyConvertingIterator extends Iterator<Object> {
|
||||
|
||||
/**
|
||||
* Returns the next element which has already been converted.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Object nextConverted();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,61 +23,61 @@ import org.springframework.data.mapping.MappingBeanHelper;
|
||||
import org.springframework.data.repository.support.AbstractEntityInformation;
|
||||
|
||||
/**
|
||||
* {@link MongoEntityInformation} implementation using a {@link BasicMongoPersistentEntity} instance to lookup the necessary
|
||||
* information.
|
||||
* {@link MongoEntityInformation} implementation using a {@link BasicMongoPersistentEntity} instance to lookup the
|
||||
* necessary information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingMongoEntityInformation<T, ID extends Serializable> extends AbstractEntityInformation<T, ID>
|
||||
implements MongoEntityInformation<T, ID> {
|
||||
implements MongoEntityInformation<T, ID> {
|
||||
|
||||
private final MongoPersistentEntity<T> entityMetadata;
|
||||
private final MongoPersistentEntity<T> entityMetadata;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity}.
|
||||
*
|
||||
* @param domainClass
|
||||
* @param entity
|
||||
*/
|
||||
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity) {
|
||||
super(entity.getType());
|
||||
this.entityMetadata = entity;
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity}.
|
||||
*
|
||||
* @param domainClass
|
||||
* @param entity
|
||||
*/
|
||||
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity) {
|
||||
super(entity.getType());
|
||||
this.entityMetadata = entity;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getId(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public ID getId(T entity) {
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getId(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public ID getId(T entity) {
|
||||
|
||||
MongoPersistentProperty idProperty = entityMetadata.getIdProperty();
|
||||
MongoPersistentProperty idProperty = entityMetadata.getIdProperty();
|
||||
|
||||
try {
|
||||
return (ID) MappingBeanHelper.getProperty(entity, idProperty, idProperty.getType(), false);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return (ID) MappingBeanHelper.getProperty(entity, idProperty, idProperty.getType(), false);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getIdType()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Class<ID> getIdType() {
|
||||
return (Class<ID>) entityMetadata.getIdProperty().getType();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getIdType()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Class<ID> getIdType() {
|
||||
return (Class<ID>) entityMetadata.getIdProperty().getType();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoEntityInformation#getCollectionName()
|
||||
*/
|
||||
public String getCollectionName() {
|
||||
return entityMetadata.getCollection();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoEntityInformation#getCollectionName()
|
||||
*/
|
||||
public String getCollectionName() {
|
||||
return entityMetadata.getCollection();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoEntityInformation#getIdAttribute()
|
||||
*/
|
||||
public String getIdAttribute() {
|
||||
return entityMetadata.getIdProperty().getName();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.repository.MongoEntityInformation#getIdAttribute()
|
||||
*/
|
||||
public String getIdAttribute() {
|
||||
return entityMetadata.getIdProperty().getName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,20 +46,20 @@ import com.mysema.query.apt.Processor;
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_6)
|
||||
public class MongoAnnotationProcessor extends AbstractProcessor {
|
||||
|
||||
private Class<? extends Annotation> entities, entity, embedded, skip;
|
||||
private Class<? extends Annotation> entities, entity, embedded, skip;
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Running " + getClass().getSimpleName());
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Running " + getClass().getSimpleName());
|
||||
|
||||
DefaultConfiguration configuration = new DefaultConfiguration(roundEnv, processingEnv.getOptions(),
|
||||
Collections.<String> emptySet(), QueryEntities.class, Document.class, QuerySupertype.class,
|
||||
QueryEmbeddable.class, QueryEmbedded.class, QueryTransient.class);
|
||||
configuration.setUnknownAsEmbedded(true);
|
||||
DefaultConfiguration configuration = new DefaultConfiguration(roundEnv, processingEnv.getOptions(),
|
||||
Collections.<String> emptySet(), QueryEntities.class, Document.class, QuerySupertype.class,
|
||||
QueryEmbeddable.class, QueryEmbedded.class, QueryTransient.class);
|
||||
configuration.setUnknownAsEmbedded(true);
|
||||
|
||||
Processor processor = new Processor(processingEnv, roundEnv, configuration);
|
||||
processor.process();
|
||||
return true;
|
||||
}
|
||||
Processor processor = new Processor(processingEnv, roundEnv, configuration);
|
||||
processor.process();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,22 +21,22 @@ import org.springframework.data.repository.support.EntityInformation;
|
||||
|
||||
/**
|
||||
* Mongo specific {@link EntityInformation}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoEntityInformation<T, ID extends Serializable> extends EntityInformation<T, ID> {
|
||||
|
||||
/**
|
||||
* Returns the name of the collection the entity shall be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCollectionName();
|
||||
/**
|
||||
* Returns the name of the collection the entity shall be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCollectionName();
|
||||
|
||||
/**
|
||||
* Returns the attribute that the id will be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getIdAttribute();
|
||||
/**
|
||||
* Returns the attribute that the id will be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getIdAttribute();
|
||||
}
|
||||
@@ -38,174 +38,165 @@ import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.Part.Type;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
|
||||
/**
|
||||
* Custom query creator to create Mongo criterias.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(MongoQueryCreator.class);
|
||||
private static final Log LOG = LogFactory.getLog(MongoQueryCreator.class);
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoQueryCreator} from the given {@link PartTree} and {@link ParametersParameterAccessor}.
|
||||
*
|
||||
* @param tree
|
||||
* @param accessor
|
||||
*/
|
||||
public MongoQueryCreator(PartTree tree, ParameterAccessor accessor) {
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoQueryCreator} from the given {@link PartTree}
|
||||
* and {@link ParametersParameterAccessor}.
|
||||
*
|
||||
* @param tree
|
||||
* @param accessor
|
||||
*/
|
||||
public MongoQueryCreator(PartTree tree, ParameterAccessor accessor) {
|
||||
super(tree, accessor);
|
||||
}
|
||||
|
||||
super(tree, accessor);
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#create(org.springframework.data.repository.query.parser.Part, java.util.Iterator)
|
||||
*/
|
||||
@Override
|
||||
protected Query create(Part part, Iterator<Object> iterator) {
|
||||
|
||||
Criteria criteria = from(part.getType(), where(part.getProperty().toDotPath()),
|
||||
(PotentiallyConvertingIterator) iterator);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#create(org.springframework.data.repository.query.parser.Part, java.util.Iterator)
|
||||
*/
|
||||
@Override
|
||||
protected Query create(Part part, Iterator<Object> iterator) {
|
||||
return new Query(criteria);
|
||||
}
|
||||
|
||||
Criteria criteria = from(part.getType(),
|
||||
where(part.getProperty().toDotPath()), (PotentiallyConvertingIterator) iterator);
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#and(org.springframework.data.repository.query.parser.Part, java.lang.Object, java.util.Iterator)
|
||||
*/
|
||||
@Override
|
||||
protected Query and(Part part, Query base, Iterator<Object> iterator) {
|
||||
|
||||
return new Query(criteria);
|
||||
}
|
||||
Criteria criteria = from(part.getType(), where(part.getProperty().toDotPath()),
|
||||
(PotentiallyConvertingIterator) iterator);
|
||||
return base.addCriteria(criteria);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.query.parser.AbstractQueryCreator
|
||||
* #or(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected Query or(Query base, Query query) {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#and(org.springframework.data.repository.query.parser.Part, java.lang.Object, java.util.Iterator)
|
||||
*/
|
||||
@Override
|
||||
protected Query and(Part part, Query base,
|
||||
Iterator<Object> iterator) {
|
||||
return new Query().or(base, query);
|
||||
}
|
||||
|
||||
Criteria criteria = from(part.getType(), where(part.getProperty().toDotPath()),
|
||||
(PotentiallyConvertingIterator) iterator);
|
||||
return base.addCriteria(criteria);
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.query.parser.AbstractQueryCreator
|
||||
* #complete(java.lang.Object, org.springframework.data.domain.Sort)
|
||||
*/
|
||||
@Override
|
||||
protected Query complete(Query query, Sort sort) {
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Created query " + query.getQueryObject());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.query.parser.AbstractQueryCreator
|
||||
* #or(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected Query or(Query base, Query query) {
|
||||
return query;
|
||||
}
|
||||
|
||||
return new Query().or(base, query);
|
||||
}
|
||||
/**
|
||||
* Populates the given {@link CriteriaDefinition} depending on the {@link Type} given.
|
||||
*
|
||||
* @param type
|
||||
* @param criteria
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
private Criteria from(Type type, Criteria criteria, PotentiallyConvertingIterator parameters) {
|
||||
|
||||
switch (type) {
|
||||
case GREATER_THAN:
|
||||
return criteria.gt(parameters.nextConverted());
|
||||
case LESS_THAN:
|
||||
return criteria.lt(parameters.nextConverted());
|
||||
case BETWEEN:
|
||||
return criteria.gt(parameters.nextConverted()).lt(parameters.nextConverted());
|
||||
case IS_NOT_NULL:
|
||||
return criteria.ne(null);
|
||||
case IS_NULL:
|
||||
return criteria.is(null);
|
||||
case NOT_IN:
|
||||
return criteria.nin(nextAsArray(parameters));
|
||||
case IN:
|
||||
return criteria.in(nextAsArray(parameters));
|
||||
case LIKE:
|
||||
String value = parameters.next().toString();
|
||||
return criteria.is(toLikeRegex(value));
|
||||
case NEAR:
|
||||
return criteria.near(nextAs(parameters, Point.class));
|
||||
case WITHIN:
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.query.parser.AbstractQueryCreator
|
||||
* #complete(java.lang.Object, org.springframework.data.domain.Sort)
|
||||
*/
|
||||
@Override
|
||||
protected Query complete(Query query, Sort sort) {
|
||||
Object parameter = parameters.next();
|
||||
if (parameter instanceof Box) {
|
||||
return criteria.withinBox((Box) parameter);
|
||||
} else if (parameter instanceof Circle) {
|
||||
return criteria.withinCenter((Circle) parameter);
|
||||
}
|
||||
throw new IllegalArgumentException("Parameter has to be either Box or Circle!");
|
||||
case SIMPLE_PROPERTY:
|
||||
return criteria.is(parameters.nextConverted());
|
||||
case NEGATING_SIMPLE_PROPERTY:
|
||||
return criteria.not().is(parameters.nextConverted());
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Created query " + query.getQueryObject());
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported keyword!");
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
/**
|
||||
* Returns the next element from the given {@link Iterator} expecting it to be of a certain type.
|
||||
*
|
||||
* @param <T>
|
||||
* @param iterator
|
||||
* @param type
|
||||
* @throws IllegalArgumentException
|
||||
* in case the next element in the iterator is not of the given type.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T nextAs(Iterator<Object> iterator, Class<T> type) {
|
||||
Object parameter = iterator.next();
|
||||
if (parameter.getClass().isAssignableFrom(type)) {
|
||||
return (T) parameter;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Expected parameter type of %s but got %s!", type,
|
||||
parameter.getClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the given {@link CriteriaDefinition} depending on the {@link Type} given.
|
||||
*
|
||||
* @param type
|
||||
* @param criteria
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
private Criteria from(Type type, Criteria criteria, PotentiallyConvertingIterator parameters) {
|
||||
private Object[] nextAsArray(PotentiallyConvertingIterator iterator) {
|
||||
Object next = iterator.nextConverted();
|
||||
|
||||
switch (type) {
|
||||
case GREATER_THAN:
|
||||
return criteria.gt(parameters.nextConverted());
|
||||
case LESS_THAN:
|
||||
return criteria.lt(parameters.nextConverted());
|
||||
case BETWEEN:
|
||||
return criteria.gt(parameters.nextConverted()).lt(parameters.nextConverted());
|
||||
case IS_NOT_NULL:
|
||||
return criteria.ne(null);
|
||||
case IS_NULL:
|
||||
return criteria.is(null);
|
||||
case NOT_IN:
|
||||
return criteria.nin(nextAsArray(parameters));
|
||||
case IN:
|
||||
return criteria.in(nextAsArray(parameters));
|
||||
case LIKE:
|
||||
String value = parameters.next().toString();
|
||||
return criteria.is(toLikeRegex(value));
|
||||
case NEAR:
|
||||
return criteria.near(nextAs(parameters, Point.class));
|
||||
case WITHIN:
|
||||
|
||||
Object parameter = parameters.next();
|
||||
if (parameter instanceof Box) {
|
||||
return criteria.withinBox((Box) parameter);
|
||||
} else if (parameter instanceof Circle) {
|
||||
return criteria.withinCenter((Circle) parameter);
|
||||
}
|
||||
throw new IllegalArgumentException("Parameter has to be either Box or Circle!");
|
||||
case SIMPLE_PROPERTY:
|
||||
return criteria.is(parameters.nextConverted());
|
||||
case NEGATING_SIMPLE_PROPERTY:
|
||||
return criteria.not().is(parameters.nextConverted());
|
||||
}
|
||||
if (next instanceof Collection) {
|
||||
return ((Collection<?>) next).toArray();
|
||||
} else if (next.getClass().isArray()) {
|
||||
return (Object[]) next;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unsupported keyword!");
|
||||
}
|
||||
return new Object[] { next };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element from the given {@link Iterator} expecting it to be of a certain type.
|
||||
*
|
||||
* @param <T>
|
||||
* @param iterator
|
||||
* @param type
|
||||
* @throws IllegalArgumentException
|
||||
* in case the next element in the iterator is not of the given type.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T nextAs(Iterator<Object> iterator, Class<T> type) {
|
||||
Object parameter = iterator.next();
|
||||
if (parameter.getClass().isAssignableFrom(type)) {
|
||||
return (T) parameter;
|
||||
}
|
||||
private Pattern toLikeRegex(String source) {
|
||||
|
||||
throw new IllegalArgumentException(String.format("Expected parameter type of %s but got %s!", type,
|
||||
parameter.getClass()));
|
||||
}
|
||||
|
||||
private Object[] nextAsArray(PotentiallyConvertingIterator iterator) {
|
||||
Object next = iterator.nextConverted();
|
||||
|
||||
if (next instanceof Collection) {
|
||||
return ((Collection<?>) next).toArray();
|
||||
} else if (next.getClass().isArray()) {
|
||||
return (Object[]) next;
|
||||
}
|
||||
|
||||
return new Object[]{next};
|
||||
}
|
||||
|
||||
private Pattern toLikeRegex(String source) {
|
||||
|
||||
String regex = source.replaceAll("\\*", ".*");
|
||||
return Pattern.compile(regex);
|
||||
}
|
||||
String regex = source.replaceAll("\\*", ".*");
|
||||
return Pattern.compile(regex);
|
||||
}
|
||||
}
|
||||
@@ -32,68 +32,68 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
class MongoQueryMethod extends QueryMethod {
|
||||
|
||||
private final Method method;
|
||||
private final MongoEntityInformation<?, ?> entityInformation;
|
||||
private final Method method;
|
||||
private final MongoEntityInformation<?, ?> entityInformation;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoQueryMethod} from the given {@link Method}.
|
||||
*
|
||||
* @param method
|
||||
*/
|
||||
public MongoQueryMethod(Method method, RepositoryMetadata metadata, EntityInformationCreator entityInformationCreator) {
|
||||
super(method, metadata);
|
||||
this.method = method;
|
||||
this.entityInformation = entityInformationCreator.getEntityInformation(ClassUtils.getReturnedDomainClass(method));
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link MongoQueryMethod} from the given {@link Method}.
|
||||
*
|
||||
* @param method
|
||||
*/
|
||||
public MongoQueryMethod(Method method, RepositoryMetadata metadata, EntityInformationCreator entityInformationCreator) {
|
||||
super(method, metadata);
|
||||
this.method = method;
|
||||
this.entityInformation = entityInformationCreator.getEntityInformation(ClassUtils.getReturnedDomainClass(method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the method has an annotated query.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean hasAnnotatedQuery() {
|
||||
return getAnnotatedQuery() != null;
|
||||
}
|
||||
/**
|
||||
* Returns whether the method has an annotated query.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean hasAnnotatedQuery() {
|
||||
return getAnnotatedQuery() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query string declared in a {@link Query} annotation or {@literal null} if neither the annotation found
|
||||
* nor the attribute was specified.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getAnnotatedQuery() {
|
||||
/**
|
||||
* Returns the query string declared in a {@link Query} annotation or {@literal null} if neither the annotation found
|
||||
* nor the attribute was specified.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getAnnotatedQuery() {
|
||||
|
||||
String query = (String) AnnotationUtils.getValue(getQueryAnnotation());
|
||||
return StringUtils.hasText(query) ? query : null;
|
||||
}
|
||||
String query = (String) AnnotationUtils.getValue(getQueryAnnotation());
|
||||
return StringUtils.hasText(query) ? query : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field specification to be used for the query.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getFieldSpecification() {
|
||||
/**
|
||||
* Returns the field specification to be used for the query.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getFieldSpecification() {
|
||||
|
||||
String value = (String) AnnotationUtils.getValue(getQueryAnnotation(), "fields");
|
||||
return StringUtils.hasText(value) ? value : null;
|
||||
}
|
||||
String value = (String) AnnotationUtils.getValue(getQueryAnnotation(), "fields");
|
||||
return StringUtils.hasText(value) ? value : null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.QueryMethod#getEntityMetadata()
|
||||
*/
|
||||
@Override
|
||||
public MongoEntityInformation<?, ?> getEntityInformation() {
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.QueryMethod#getEntityMetadata()
|
||||
*/
|
||||
@Override
|
||||
public MongoEntityInformation<?, ?> getEntityInformation() {
|
||||
|
||||
return entityInformation;
|
||||
}
|
||||
return entityInformation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Query} annotation that is applied to the method or {@code null} if none available.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Query getQueryAnnotation() {
|
||||
/**
|
||||
* Returns the {@link Query} annotation that is applied to the method or {@code null} if none available.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Query getQueryAnnotation() {
|
||||
|
||||
return method.getAnnotation(Query.class);
|
||||
}
|
||||
return method.getAnnotation(Query.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
|
||||
/**
|
||||
* Mongo specific {@link org.springframework.data.repository.Repository} interface.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
|
||||
@@ -34,18 +34,18 @@ public interface MongoRepository<T, ID extends Serializable> extends PagingAndSo
|
||||
* @see org.springframework.data.repository.Repository#save(java.lang.Iterable)
|
||||
*/
|
||||
List<T> save(Iterable<? extends T> entites);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#findAll()
|
||||
*/
|
||||
List<T> findAll();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
|
||||
*/
|
||||
List<T> findAll(Sort sort);
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#findAll()
|
||||
*/
|
||||
List<T> findAll();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
|
||||
*/
|
||||
List<T> findAll(Sort sort);
|
||||
}
|
||||
|
||||
@@ -50,272 +50,277 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.FactoryBean} to create {@link MongoRepository} instances.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends
|
||||
RepositoryFactoryBeanSupport<T, S, ID> {
|
||||
RepositoryFactoryBeanSupport<T, S, ID> {
|
||||
|
||||
private MongoTemplate template;
|
||||
private MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
private MongoTemplate template;
|
||||
private MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
|
||||
/**
|
||||
* Configures the {@link MongoTemplate} to be used.
|
||||
*
|
||||
* @param template the template to set
|
||||
*/
|
||||
public void setTemplate(MongoTemplate template) {
|
||||
/**
|
||||
* Configures the {@link MongoTemplate} to be used.
|
||||
*
|
||||
* @param template
|
||||
* the template to set
|
||||
*/
|
||||
public void setTemplate(MongoTemplate template) {
|
||||
|
||||
this.template = template;
|
||||
}
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MappingContext} used with the underlying {@link MongoTemplate}.
|
||||
*
|
||||
* @param mappingContext the mappingContext to set
|
||||
*/
|
||||
public void setMappingContext(MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
/**
|
||||
* Sets the {@link MappingContext} used with the underlying {@link MongoTemplate}.
|
||||
*
|
||||
* @param mappingContext
|
||||
* the mappingContext to set
|
||||
*/
|
||||
public void setMappingContext(MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactoryBeanSupport
|
||||
* #createRepositoryFactory()
|
||||
*/
|
||||
@Override
|
||||
protected RepositoryFactorySupport createRepositoryFactory() {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactoryBeanSupport
|
||||
* #createRepositoryFactory()
|
||||
*/
|
||||
@Override
|
||||
protected RepositoryFactorySupport createRepositoryFactory() {
|
||||
|
||||
MongoRepositoryFactory factory = new MongoRepositoryFactory(template, mappingContext);
|
||||
factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(template));
|
||||
return factory;
|
||||
}
|
||||
MongoRepositoryFactory factory = new MongoRepositoryFactory(template, mappingContext);
|
||||
factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(template));
|
||||
return factory;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactoryBeanSupport
|
||||
* #afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactoryBeanSupport
|
||||
* #afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
super.afterPropertiesSet();
|
||||
Assert.notNull(template, "MongoTemplate must not be null!");
|
||||
Assert.notNull(mappingContext, "MappingContext must not be null!");
|
||||
}
|
||||
super.afterPropertiesSet();
|
||||
Assert.notNull(template, "MongoTemplate must not be null!");
|
||||
Assert.notNull(mappingContext, "MappingContext must not be null!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository to create {@link MongoRepository} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class MongoRepositoryFactory extends RepositoryFactorySupport {
|
||||
/**
|
||||
* Repository to create {@link MongoRepository} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class MongoRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
private final MongoTemplate template;
|
||||
private final EntityInformationCreator entityInformationCreator;
|
||||
private final MongoTemplate template;
|
||||
private final EntityInformationCreator entityInformationCreator;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoRepositoryFactory} with the given {@link MongoTemplate} and {@link MappingContext}.
|
||||
*
|
||||
* @param template must not be {@literal null}
|
||||
* @param mappingContext
|
||||
*/
|
||||
public MongoRepositoryFactory(MongoTemplate template, MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
/**
|
||||
* Creates a new {@link MongoRepositoryFactory} with the given {@link MongoTemplate} and {@link MappingContext}.
|
||||
*
|
||||
* @param template
|
||||
* must not be {@literal null}
|
||||
* @param mappingContext
|
||||
*/
|
||||
public MongoRepositoryFactory(MongoTemplate template,
|
||||
MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
|
||||
Assert.notNull(template);
|
||||
Assert.notNull(mappingContext);
|
||||
this.template = template;
|
||||
this.entityInformationCreator = new EntityInformationCreator(mappingContext);
|
||||
}
|
||||
Assert.notNull(template);
|
||||
Assert.notNull(mappingContext);
|
||||
this.template = template;
|
||||
this.entityInformationCreator = new EntityInformationCreator(mappingContext);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport
|
||||
* #getRepositoryBaseClass()
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport
|
||||
* #getRepositoryBaseClass()
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
|
||||
|
||||
return isQueryDslRepository(metadata.getRepositoryInterface()) ? QueryDslMongoRepository.class
|
||||
: SimpleMongoRepository.class;
|
||||
}
|
||||
return isQueryDslRepository(metadata.getRepositoryInterface()) ? QueryDslMongoRepository.class
|
||||
: SimpleMongoRepository.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport
|
||||
* #getTargetRepository
|
||||
* (org.springframework.data.repository.support.RepositoryMetadata)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
protected Object getTargetRepository(RepositoryMetadata metadata) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport
|
||||
* #getTargetRepository
|
||||
* (org.springframework.data.repository.support.RepositoryMetadata)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected Object getTargetRepository(RepositoryMetadata metadata) {
|
||||
|
||||
Class<?> repositoryInterface = metadata.getRepositoryInterface();
|
||||
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainClass());
|
||||
Class<?> repositoryInterface = metadata.getRepositoryInterface();
|
||||
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainClass());
|
||||
|
||||
if (isQueryDslRepository(repositoryInterface)) {
|
||||
return new QueryDslMongoRepository(entityInformation, template);
|
||||
} else {
|
||||
return new SimpleMongoRepository(entityInformation, template);
|
||||
}
|
||||
}
|
||||
if (isQueryDslRepository(repositoryInterface)) {
|
||||
return new QueryDslMongoRepository(entityInformation, template);
|
||||
} else {
|
||||
return new SimpleMongoRepository(entityInformation, template);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isQueryDslRepository(Class<?> repositoryInterface) {
|
||||
private static boolean isQueryDslRepository(Class<?> repositoryInterface) {
|
||||
|
||||
return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
|
||||
}
|
||||
return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport
|
||||
* #getQueryLookupStrategy
|
||||
* (org.springframework.data.repository.query.QueryLookupStrategy.Key)
|
||||
*/
|
||||
@Override
|
||||
protected QueryLookupStrategy getQueryLookupStrategy(Key key) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport
|
||||
* #getQueryLookupStrategy
|
||||
* (org.springframework.data.repository.query.QueryLookupStrategy.Key)
|
||||
*/
|
||||
@Override
|
||||
protected QueryLookupStrategy getQueryLookupStrategy(Key key) {
|
||||
|
||||
return new MongoQueryLookupStrategy();
|
||||
}
|
||||
return new MongoQueryLookupStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link QueryLookupStrategy} to create {@link PartTreeMongoQuery} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class MongoQueryLookupStrategy implements QueryLookupStrategy {
|
||||
/**
|
||||
* {@link QueryLookupStrategy} to create {@link PartTreeMongoQuery} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class MongoQueryLookupStrategy implements QueryLookupStrategy {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.query.QueryLookupStrategy
|
||||
* #resolveQuery(java.lang.reflect.Method, java.lang.Class)
|
||||
*/
|
||||
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.query.QueryLookupStrategy
|
||||
* #resolveQuery(java.lang.reflect.Method, java.lang.Class)
|
||||
*/
|
||||
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata) {
|
||||
|
||||
MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, entityInformationCreator);
|
||||
MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, entityInformationCreator);
|
||||
|
||||
if (queryMethod.hasAnnotatedQuery()) {
|
||||
return new StringBasedMongoQuery(queryMethod, template);
|
||||
} else {
|
||||
return new PartTreeMongoQuery(queryMethod, template);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (queryMethod.hasAnnotatedQuery()) {
|
||||
return new StringBasedMongoQuery(queryMethod, template);
|
||||
} else {
|
||||
return new PartTreeMongoQuery(queryMethod, template);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryFactorySupport#validate(org.springframework.data.repository.support.RepositoryMetadata)
|
||||
*/
|
||||
@Override
|
||||
protected void validate(RepositoryMetadata metadata) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryFactorySupport#validate(org.springframework.data.repository.support.RepositoryMetadata)
|
||||
*/
|
||||
@Override
|
||||
protected void validate(RepositoryMetadata metadata) {
|
||||
|
||||
Class<?> idClass = metadata.getIdClass();
|
||||
if (!MongoPropertyDescriptor.SUPPORTED_ID_CLASSES.contains(idClass)) {
|
||||
throw new IllegalArgumentException(String.format("Unsupported id class! Only %s are supported!",
|
||||
StringUtils.collectionToCommaDelimitedString(MongoPropertyDescriptor.SUPPORTED_ID_CLASSES)));
|
||||
}
|
||||
}
|
||||
Class<?> idClass = metadata.getIdClass();
|
||||
if (!MongoPropertyDescriptor.SUPPORTED_ID_CLASSES.contains(idClass)) {
|
||||
throw new IllegalArgumentException(String.format("Unsupported id class! Only %s are supported!",
|
||||
StringUtils.collectionToCommaDelimitedString(MongoPropertyDescriptor.SUPPORTED_ID_CLASSES)));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport
|
||||
* #getEntityInformation(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport
|
||||
* #getEntityInformation(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
|
||||
return entityInformationCreator.getEntityInformation(domainClass);
|
||||
}
|
||||
}
|
||||
return entityInformationCreator.getEntityInformation(domainClass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple wrapper to to create {@link MongoEntityInformation} instances based on a {@link MappingContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static class EntityInformationCreator {
|
||||
/**
|
||||
* Simple wrapper to to create {@link MongoEntityInformation} instances based on a {@link MappingContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static class EntityInformationCreator {
|
||||
|
||||
private final MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
private final MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
|
||||
public EntityInformationCreator(MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
Assert.notNull(mappingContext);
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
public EntityInformationCreator(MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
Assert.notNull(mappingContext);
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
MongoPersistentEntity<T> persistentEntity = (MongoPersistentEntity<T>) mappingContext.getPersistentEntity(domainClass);
|
||||
return new MappingMongoEntityInformation<T, ID>(persistentEntity);
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
MongoPersistentEntity<T> persistentEntity = (MongoPersistentEntity<T>) mappingContext
|
||||
.getPersistentEntity(domainClass);
|
||||
return new MappingMongoEntityInformation<T, ID>(persistentEntity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link QueryCreationListener} inspecting {@link PartTreeMongoQuery}s and creating an index for the properties it
|
||||
* refers to.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class IndexEnsuringQueryCreationListener implements QueryCreationListener<PartTreeMongoQuery> {
|
||||
/**
|
||||
* {@link QueryCreationListener} inspecting {@link PartTreeMongoQuery}s and creating an index for the properties it
|
||||
* refers to.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class IndexEnsuringQueryCreationListener implements QueryCreationListener<PartTreeMongoQuery> {
|
||||
|
||||
private static final Set<Type> GEOSPATIAL_TYPES = new HashSet<Part.Type>(Arrays.asList(Type.NEAR, Type.WITHIN));
|
||||
private static final Log LOG = LogFactory.getLog(IndexEnsuringQueryCreationListener.class);
|
||||
private final MongoOperations operations;
|
||||
private static final Set<Type> GEOSPATIAL_TYPES = new HashSet<Part.Type>(Arrays.asList(Type.NEAR, Type.WITHIN));
|
||||
private static final Log LOG = LogFactory.getLog(IndexEnsuringQueryCreationListener.class);
|
||||
private final MongoOperations operations;
|
||||
|
||||
public IndexEnsuringQueryCreationListener(MongoOperations operations) {
|
||||
public IndexEnsuringQueryCreationListener(MongoOperations operations) {
|
||||
|
||||
this.operations = operations;
|
||||
}
|
||||
this.operations = operations;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.QueryCreationListener
|
||||
* #onCreation(org.springframework.data.repository
|
||||
* .query.RepositoryQuery)
|
||||
*/
|
||||
public void onCreation(PartTreeMongoQuery query) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.QueryCreationListener
|
||||
* #onCreation(org.springframework.data.repository
|
||||
* .query.RepositoryQuery)
|
||||
*/
|
||||
public void onCreation(PartTreeMongoQuery query) {
|
||||
|
||||
PartTree tree = query.getTree();
|
||||
Index index = new Index();
|
||||
index.named(query.getQueryMethod().getName());
|
||||
Sort sort = tree.getSort();
|
||||
PartTree tree = query.getTree();
|
||||
Index index = new Index();
|
||||
index.named(query.getQueryMethod().getName());
|
||||
Sort sort = tree.getSort();
|
||||
|
||||
for (Part part : tree.getParts()) {
|
||||
if (GEOSPATIAL_TYPES.contains(part.getType())) {
|
||||
return;
|
||||
}
|
||||
String property = part.getProperty().toDotPath();
|
||||
Order order = toOrder(sort, property);
|
||||
index.on(property, order);
|
||||
}
|
||||
for (Part part : tree.getParts()) {
|
||||
if (GEOSPATIAL_TYPES.contains(part.getType())) {
|
||||
return;
|
||||
}
|
||||
String property = part.getProperty().toDotPath();
|
||||
Order order = toOrder(sort, property);
|
||||
index.on(property, order);
|
||||
}
|
||||
|
||||
MongoEntityInformation<?, ?> metadata = query.getQueryMethod().getEntityInformation();
|
||||
operations.ensureIndex(metadata.getCollectionName(), index);
|
||||
LOG.debug(String.format("Created %s!", index));
|
||||
}
|
||||
MongoEntityInformation<?, ?> metadata = query.getQueryMethod().getEntityInformation();
|
||||
operations.ensureIndex(metadata.getCollectionName(), index);
|
||||
LOG.debug(String.format("Created %s!", index));
|
||||
}
|
||||
|
||||
private static Order toOrder(Sort sort, String property) {
|
||||
private static Order toOrder(Sort sort, String property) {
|
||||
|
||||
if (sort == null) {
|
||||
return Order.DESCENDING;
|
||||
}
|
||||
if (sort == null) {
|
||||
return Order.DESCENDING;
|
||||
}
|
||||
|
||||
org.springframework.data.domain.Sort.Order order = sort.getOrderFor(property);
|
||||
return order == null ? Order.DESCENDING : order.isAscending() ? Order.ASCENDING : Order.DESCENDING;
|
||||
}
|
||||
}
|
||||
org.springframework.data.domain.Sort.Order order = sort.getOrderFor(property);
|
||||
return order == null ? Order.DESCENDING : order.isAscending() ? Order.ASCENDING : Order.DESCENDING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,43 +23,43 @@ import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
/**
|
||||
* {@link RepositoryQuery} implementation for Mongo.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PartTreeMongoQuery extends AbstractMongoQuery {
|
||||
|
||||
private final PartTree tree;
|
||||
private final PartTree tree;
|
||||
|
||||
/**
|
||||
* Creates a new {@link PartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}.
|
||||
*
|
||||
* @param method
|
||||
* @param template
|
||||
*/
|
||||
public PartTreeMongoQuery(MongoQueryMethod method, MongoTemplate template) {
|
||||
/**
|
||||
* Creates a new {@link PartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}.
|
||||
*
|
||||
* @param method
|
||||
* @param template
|
||||
*/
|
||||
public PartTreeMongoQuery(MongoQueryMethod method, MongoTemplate template) {
|
||||
|
||||
super(method, template);
|
||||
this.tree = new PartTree(method.getName(), method.getEntityInformation().getJavaType());
|
||||
}
|
||||
super(method, template);
|
||||
this.tree = new PartTree(method.getName(), method.getEntityInformation().getJavaType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tree
|
||||
*/
|
||||
public PartTree getTree() {
|
||||
return tree;
|
||||
}
|
||||
/**
|
||||
* @return the tree
|
||||
*/
|
||||
public PartTree getTree() {
|
||||
return tree;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.AbstractMongoQuery#createQuery(org.springframework.data.
|
||||
* document.mongodb.repository.ConvertingParameterAccessor)
|
||||
*/
|
||||
@Override
|
||||
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.AbstractMongoQuery#createQuery(org.springframework.data.
|
||||
* document.mongodb.repository.ConvertingParameterAccessor)
|
||||
*/
|
||||
@Override
|
||||
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
||||
|
||||
MongoQueryCreator creator = new MongoQueryCreator(tree, accessor);
|
||||
return creator.createQuery();
|
||||
}
|
||||
MongoQueryCreator creator = new MongoQueryCreator(tree, accessor);
|
||||
return creator.createQuery();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,19 +28,19 @@ import java.lang.annotation.*;
|
||||
@Documented
|
||||
public @interface Query {
|
||||
|
||||
/**
|
||||
* Takes a MongoDB JSON string to define the actual query to be executed. This one will take precendece over the
|
||||
* method name then.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String value() default "";
|
||||
/**
|
||||
* Takes a MongoDB JSON string to define the actual query to be executed. This one will take precendece over the
|
||||
* method name then.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* Defines the fields that should be returned for the given query. Note that only these fields will make it into the
|
||||
* domain object returned.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String fields() default "";
|
||||
/**
|
||||
* Defines the fields that should be returned for the given query. Note that only these fields will make it into the
|
||||
* domain object returned.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String fields() default "";
|
||||
}
|
||||
|
||||
@@ -40,250 +40,221 @@ import com.mysema.query.types.OrderSpecifier;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.path.PathBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* Special QueryDsl based repository implementation that allows execution
|
||||
* {@link Predicate}s in various forms. TODO: Extract {@link EntityPathResolver}
|
||||
* into Spring Data Commons TODO: Refactor Spring Data JPA to use this common
|
||||
* Special QueryDsl based repository implementation that allows execution {@link Predicate}s in various forms. TODO:
|
||||
* Extract {@link EntityPathResolver} into Spring Data Commons TODO: Refactor Spring Data JPA to use this common
|
||||
* infrastructure
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class QueryDslMongoRepository<T, ID extends Serializable> extends
|
||||
SimpleMongoRepository<T, ID> implements QueryDslPredicateExecutor<T> {
|
||||
public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> implements
|
||||
QueryDslPredicateExecutor<T> {
|
||||
|
||||
private final MongoConverterTransformer transformer;
|
||||
private final MongodbSerializer serializer;
|
||||
private final PathBuilder<T> builder;
|
||||
private final MongoConverterTransformer transformer;
|
||||
private final MongodbSerializer serializer;
|
||||
private final PathBuilder<T> builder;
|
||||
|
||||
/**
|
||||
* Creates a new {@link QueryDslMongoRepository} for the given {@link EntityMetadata} and {@link MongoTemplate}. Uses
|
||||
* the {@link SimpleEntityPathResolver} to create an {@link EntityPath} for the given domain class.
|
||||
*
|
||||
* @param entityInformation
|
||||
* @param template
|
||||
*/
|
||||
public QueryDslMongoRepository(MongoEntityInformation<T, ID> entityInformation, MongoTemplate template) {
|
||||
|
||||
/**
|
||||
* Creates a new {@link QueryDslMongoRepository} for the given
|
||||
* {@link EntityMetadata} and {@link MongoTemplate}. Uses the
|
||||
* {@link SimpleEntityPathResolver} to create an {@link EntityPath} for the
|
||||
* given domain class.
|
||||
*
|
||||
* @param entityInformation
|
||||
* @param template
|
||||
*/
|
||||
public QueryDslMongoRepository(
|
||||
MongoEntityInformation<T, ID> entityInformation, MongoTemplate template) {
|
||||
this(entityInformation, template, SimpleEntityPathResolver.INSTANCE);
|
||||
}
|
||||
|
||||
this(entityInformation, template, SimpleEntityPathResolver.INSTANCE);
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link QueryDslMongoRepository} for the given {@link MongoEntityInformation}, {@link MongoTemplate}
|
||||
* and {@link EntityPathResolver}.
|
||||
*
|
||||
* @param entityInformation
|
||||
* @param template
|
||||
* @param resolver
|
||||
*/
|
||||
public QueryDslMongoRepository(MongoEntityInformation<T, ID> entityInformation, MongoTemplate template,
|
||||
EntityPathResolver resolver) {
|
||||
|
||||
super(entityInformation, template);
|
||||
this.transformer = new MongoConverterTransformer(template.getConverter());
|
||||
this.serializer = new MongodbSerializer();
|
||||
|
||||
/**
|
||||
* Creates a new {@link QueryDslMongoRepository} for the given {@link MongoEntityInformation},
|
||||
* {@link MongoTemplate} and {@link EntityPathResolver}.
|
||||
*
|
||||
* @param entityInformation
|
||||
* @param template
|
||||
* @param resolver
|
||||
*/
|
||||
public QueryDslMongoRepository(
|
||||
MongoEntityInformation<T, ID> entityInformation,
|
||||
MongoTemplate template, EntityPathResolver resolver) {
|
||||
EntityPath<T> path = resolver.createPath(entityInformation.getJavaType());
|
||||
this.builder = new PathBuilder<T>(path.getType(), path.getMetadata());
|
||||
}
|
||||
|
||||
super(entityInformation, template);
|
||||
this.transformer = new MongoConverterTransformer(template.getConverter());
|
||||
this.serializer = new MongodbSerializer();
|
||||
|
||||
EntityPath<T> path = resolver.createPath(entityInformation.getJavaType());
|
||||
this.builder = new PathBuilder<T>(path.getType(), path.getMetadata());
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #findOne(com.mysema.query.types.Predicate)
|
||||
*/
|
||||
public T findOne(Predicate predicate) {
|
||||
|
||||
return createQueryFor(predicate).uniqueResult();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #findOne(com.mysema.query.types.Predicate)
|
||||
*/
|
||||
public T findOne(Predicate predicate) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #findAll(com.mysema.query.types.Predicate)
|
||||
*/
|
||||
public List<T> findAll(Predicate predicate) {
|
||||
|
||||
return createQueryFor(predicate).uniqueResult();
|
||||
}
|
||||
return createQueryFor(predicate).list();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #findAll(com.mysema.query.types.Predicate,
|
||||
* com.mysema.query.types.OrderSpecifier<?>[])
|
||||
*/
|
||||
public List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders) {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #findAll(com.mysema.query.types.Predicate)
|
||||
*/
|
||||
public List<T> findAll(Predicate predicate) {
|
||||
return createQueryFor(predicate).orderBy(orders).list();
|
||||
}
|
||||
|
||||
return createQueryFor(predicate).list();
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #findAll(com.mysema.query.types.Predicate,
|
||||
* org.springframework.data.domain.Pageable)
|
||||
*/
|
||||
public Page<T> findAll(Predicate predicate, Pageable pageable) {
|
||||
|
||||
MongodbQuery<T> countQuery = createQueryFor(predicate);
|
||||
MongodbQuery<T> query = createQueryFor(predicate);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #findAll(com.mysema.query.types.Predicate,
|
||||
* com.mysema.query.types.OrderSpecifier<?>[])
|
||||
*/
|
||||
public List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders) {
|
||||
return new PageImpl<T>(applyPagination(query, pageable).list(), pageable, countQuery.count());
|
||||
}
|
||||
|
||||
return createQueryFor(predicate).orderBy(orders).list();
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #count(com.mysema.query.types.Predicate)
|
||||
*/
|
||||
public long count(Predicate predicate) {
|
||||
|
||||
return createQueryFor(predicate).count();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #findAll(com.mysema.query.types.Predicate,
|
||||
* org.springframework.data.domain.Pageable)
|
||||
*/
|
||||
public Page<T> findAll(Predicate predicate, Pageable pageable) {
|
||||
/**
|
||||
* Creates a {@link MongodbQuery} for the given {@link Predicate}.
|
||||
*
|
||||
* @param predicate
|
||||
* @return
|
||||
*/
|
||||
private MongodbQuery<T> createQueryFor(Predicate predicate) {
|
||||
|
||||
MongodbQuery<T> countQuery = createQueryFor(predicate);
|
||||
MongodbQuery<T> query = createQueryFor(predicate);
|
||||
MongodbQuery<T> query = new MongoTemplateQuery(getMongoOperations());
|
||||
return query.where(predicate);
|
||||
}
|
||||
|
||||
return new PageImpl<T>(applyPagination(query, pageable).list(),
|
||||
pageable, countQuery.count());
|
||||
}
|
||||
/**
|
||||
* Applies the given {@link Pageable} to the given {@link MongodbQuery}.
|
||||
*
|
||||
* @param query
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
private MongodbQuery<T> applyPagination(MongodbQuery<T> query, Pageable pageable) {
|
||||
|
||||
if (pageable == null) {
|
||||
return query;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.QueryDslExecutor
|
||||
* #count(com.mysema.query.types.Predicate)
|
||||
*/
|
||||
public long count(Predicate predicate) {
|
||||
query = query.offset(pageable.getOffset()).limit(pageable.getPageSize());
|
||||
return applySorting(query, pageable.getSort());
|
||||
}
|
||||
|
||||
return createQueryFor(predicate).count();
|
||||
}
|
||||
/**
|
||||
* Applies the given {@link Sort} to the given {@link MongodbQuery}.
|
||||
*
|
||||
* @param query
|
||||
* @param sort
|
||||
* @return
|
||||
*/
|
||||
private MongodbQuery<T> applySorting(MongodbQuery<T> query, Sort sort) {
|
||||
|
||||
if (sort == null) {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link MongodbQuery} for the given {@link Predicate}.
|
||||
*
|
||||
* @param predicate
|
||||
* @return
|
||||
*/
|
||||
private MongodbQuery<T> createQueryFor(Predicate predicate) {
|
||||
for (Order order : sort) {
|
||||
query.orderBy(toOrder(order));
|
||||
}
|
||||
|
||||
MongodbQuery<T> query = new MongoTemplateQuery(getMongoOperations());
|
||||
return query.where(predicate);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a plain {@link Order} into a QueryDsl specific {@link OrderSpecifier}.
|
||||
*
|
||||
* @param order
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private OrderSpecifier<?> toOrder(Order order) {
|
||||
|
||||
/**
|
||||
* Applies the given {@link Pageable} to the given {@link MongodbQuery}.
|
||||
*
|
||||
* @param query
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
private MongodbQuery<T> applyPagination(MongodbQuery<T> query,
|
||||
Pageable pageable) {
|
||||
Expression<Object> property = builder.get(order.getProperty());
|
||||
|
||||
if (pageable == null) {
|
||||
return query;
|
||||
}
|
||||
return new OrderSpecifier(order.isAscending() ? com.mysema.query.types.Order.ASC
|
||||
: com.mysema.query.types.Order.DESC, property);
|
||||
}
|
||||
|
||||
query =
|
||||
query.offset(pageable.getOffset())
|
||||
.limit(pageable.getPageSize());
|
||||
return applySorting(query, pageable.getSort());
|
||||
}
|
||||
/**
|
||||
* Special {@link MongodbQuery} implementation to use our {@link MongoOperations} for actually accessing Mongo.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class MongoTemplateQuery extends MongodbQuery<T> {
|
||||
|
||||
public MongoTemplateQuery(MongoOperations operations) {
|
||||
super(operations.getCollection(getEntityInformation().getCollectionName()), transformer, serializer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given {@link Sort} to the given {@link MongodbQuery}.
|
||||
*
|
||||
* @param query
|
||||
* @param sort
|
||||
* @return
|
||||
*/
|
||||
private MongodbQuery<T> applySorting(MongodbQuery<T> query, Sort sort) {
|
||||
/**
|
||||
* {@link Transformer} implementation to delegate to a {@link MongoConverter}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class MongoConverterTransformer implements Transformer<DBObject, T> {
|
||||
|
||||
if (sort == null) {
|
||||
return query;
|
||||
}
|
||||
private final MongoConverter converter;
|
||||
|
||||
for (Order order : sort) {
|
||||
query.orderBy(toOrder(order));
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link MongoConverterTransformer} with the given {@link MongoConverter}.
|
||||
*
|
||||
* @param converter
|
||||
*/
|
||||
public MongoConverterTransformer(MongoConverter converter) {
|
||||
|
||||
return query;
|
||||
}
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.commons.collections15.Transformer#transform(java.lang.
|
||||
* Object)
|
||||
*/
|
||||
public T transform(DBObject input) {
|
||||
|
||||
/**
|
||||
* Transforms a plain {@link Order} into a QueryDsl specific
|
||||
* {@link OrderSpecifier}.
|
||||
*
|
||||
* @param order
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private OrderSpecifier<?> toOrder(Order order) {
|
||||
|
||||
Expression<Object> property = builder.get(order.getProperty());
|
||||
|
||||
return new OrderSpecifier(
|
||||
order.isAscending() ? com.mysema.query.types.Order.ASC
|
||||
: com.mysema.query.types.Order.DESC, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Special {@link MongodbQuery} implementation to use our
|
||||
* {@link MongoOperations} for actually accessing Mongo.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class MongoTemplateQuery extends MongodbQuery<T> {
|
||||
|
||||
public MongoTemplateQuery(MongoOperations operations) {
|
||||
super(operations.getCollection(getEntityInformation()
|
||||
.getCollectionName()), transformer, serializer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Transformer} implementation to delegate to a
|
||||
* {@link MongoConverter}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class MongoConverterTransformer implements Transformer<DBObject, T> {
|
||||
|
||||
private final MongoConverter converter;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoConverterTransformer} with the given
|
||||
* {@link MongoConverter}.
|
||||
*
|
||||
* @param converter
|
||||
*/
|
||||
public MongoConverterTransformer(MongoConverter converter) {
|
||||
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.commons.collections15.Transformer#transform(java.lang.
|
||||
* Object)
|
||||
*/
|
||||
public T transform(DBObject input) {
|
||||
|
||||
return converter.read(getEntityInformation().getJavaType(), input);
|
||||
}
|
||||
}
|
||||
return converter.read(getEntityInformation().getJavaType(), input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,8 @@ public interface QueryDslPredicateExecutor<T> {
|
||||
/**
|
||||
* Returns the number of instances that the given {@link Predicate} will return.
|
||||
*
|
||||
* @param predicate the {@link Predicate} to count instances for
|
||||
* @param predicate
|
||||
* the {@link Predicate} to count instances for
|
||||
* @return the number of instances
|
||||
*/
|
||||
long count(Predicate predicate);
|
||||
|
||||
@@ -21,65 +21,58 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
|
||||
|
||||
/**
|
||||
* Collection of utility methods to apply sorting and pagination to a
|
||||
* {@link DBCursor}.
|
||||
*
|
||||
* Collection of utility methods to apply sorting and pagination to a {@link DBCursor}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
abstract class QueryUtils {
|
||||
|
||||
private QueryUtils() {
|
||||
private QueryUtils() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given {@link Pageable} to the given {@link Query}. Will do nothing if {@link Pageable} is
|
||||
* {@literal null}.
|
||||
*
|
||||
* @param query
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
public static Query applyPagination(Query query, Pageable pageable) {
|
||||
|
||||
/**
|
||||
* Applies the given {@link Pageable} to the given {@link Query}. Will do
|
||||
* nothing if {@link Pageable} is {@literal null}.
|
||||
*
|
||||
* @param query
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
public static Query applyPagination(Query query, Pageable pageable) {
|
||||
if (pageable == null) {
|
||||
return query;
|
||||
}
|
||||
|
||||
if (pageable == null) {
|
||||
return query;
|
||||
}
|
||||
query.limit(pageable.getPageSize());
|
||||
query.skip(pageable.getOffset());
|
||||
|
||||
query.limit(pageable.getPageSize());
|
||||
query.skip(pageable.getOffset());
|
||||
return applySorting(query, pageable.getSort());
|
||||
}
|
||||
|
||||
return applySorting(query, pageable.getSort());
|
||||
}
|
||||
/**
|
||||
* Applies the given {@link Sort} to the {@link Query}. Will do nothing if {@link Sort} is {@literal null}.
|
||||
*
|
||||
* @param query
|
||||
* @param sort
|
||||
* @return
|
||||
*/
|
||||
public static Query applySorting(Query query, Sort sort) {
|
||||
|
||||
if (sort == null) {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given {@link Sort} to the {@link Query}. Will do nothing if
|
||||
* {@link Sort} is {@literal null}.
|
||||
*
|
||||
* @param query
|
||||
* @param sort
|
||||
* @return
|
||||
*/
|
||||
public static Query applySorting(Query query, Sort sort) {
|
||||
org.springframework.data.document.mongodb.query.Sort bSort = query.sort();
|
||||
|
||||
if (sort == null) {
|
||||
return query;
|
||||
}
|
||||
for (Order order : sort) {
|
||||
bSort.on(order.getProperty(),
|
||||
order.isAscending() ? org.springframework.data.document.mongodb.query.Order.ASCENDING
|
||||
: org.springframework.data.document.mongodb.query.Order.DESCENDING);
|
||||
}
|
||||
|
||||
org.springframework.data.document.mongodb.query.Sort bSort =
|
||||
query.sort();
|
||||
|
||||
for (Order order : sort) {
|
||||
bSort.on(
|
||||
order.getProperty(),
|
||||
order.isAscending() ? org.springframework.data.document.mongodb.query.Order.ASCENDING
|
||||
: org.springframework.data.document.mongodb.query.Order.DESCENDING);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,220 +40,221 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class SimpleMongoRepository<T, ID extends Serializable> implements PagingAndSortingRepository<T, ID> {
|
||||
|
||||
private final MongoTemplate template;
|
||||
private final MongoEntityInformation<T, ID> entityInformation;
|
||||
private final MongoTemplate template;
|
||||
private final MongoEntityInformation<T, ID> entityInformation;
|
||||
|
||||
/**
|
||||
* Creates a ew {@link SimpleMongoRepository} for the given {@link MongoEntityInformation} and {@link MongoTemplate}.
|
||||
*
|
||||
* @param metadata
|
||||
* @param template
|
||||
*/
|
||||
public SimpleMongoRepository(MongoEntityInformation<T, ID> metadata, MongoTemplate template) {
|
||||
/**
|
||||
* Creates a ew {@link SimpleMongoRepository} for the given {@link MongoEntityInformation} and {@link MongoTemplate}.
|
||||
*
|
||||
* @param metadata
|
||||
* @param template
|
||||
*/
|
||||
public SimpleMongoRepository(MongoEntityInformation<T, ID> metadata, MongoTemplate template) {
|
||||
|
||||
Assert.notNull(template);
|
||||
Assert.notNull(metadata);
|
||||
this.entityInformation = metadata;
|
||||
this.template = template;
|
||||
}
|
||||
Assert.notNull(template);
|
||||
Assert.notNull(metadata);
|
||||
this.entityInformation = metadata;
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#save(java.lang.Object)
|
||||
*/
|
||||
public T save(T entity) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#save(java.lang.Object)
|
||||
*/
|
||||
public T save(T entity) {
|
||||
|
||||
template.save(entityInformation.getCollectionName(), entity);
|
||||
return entity;
|
||||
}
|
||||
template.save(entityInformation.getCollectionName(), entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#save(java.lang.Iterable)
|
||||
*/
|
||||
public List<T> save(Iterable<? extends T> entities) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#save(java.lang.Iterable)
|
||||
*/
|
||||
public List<T> save(Iterable<? extends T> entities) {
|
||||
|
||||
List<T> result = new ArrayList<T>();
|
||||
List<T> result = new ArrayList<T>();
|
||||
|
||||
for (T entity : entities) {
|
||||
save(entity);
|
||||
result.add(entity);
|
||||
}
|
||||
for (T entity : entities) {
|
||||
save(entity);
|
||||
result.add(entity);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#findById(java.io.Serializable
|
||||
* )
|
||||
*/
|
||||
public T findOne(ID id) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#findById(java.io.Serializable
|
||||
* )
|
||||
*/
|
||||
public T findOne(ID id) {
|
||||
|
||||
return template.findOne(entityInformation.getCollectionName(), getIdQuery(id), entityInformation.getJavaType());
|
||||
}
|
||||
return template.findOne(entityInformation.getCollectionName(), getIdQuery(id), entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
private Query getIdQuery(Object id) {
|
||||
return new Query(getIdCriteria(id));
|
||||
}
|
||||
private Query getIdQuery(Object id) {
|
||||
return new Query(getIdCriteria(id));
|
||||
}
|
||||
|
||||
private Criteria getIdCriteria(Object id) {
|
||||
return where(entityInformation.getIdAttribute()).is(id);
|
||||
}
|
||||
private Criteria getIdCriteria(Object id) {
|
||||
return where(entityInformation.getIdAttribute()).is(id);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#exists(java.io.Serializable
|
||||
* )
|
||||
*/
|
||||
public boolean exists(ID id) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#exists(java.io.Serializable
|
||||
* )
|
||||
*/
|
||||
public boolean exists(ID id) {
|
||||
|
||||
return findOne(id) != null;
|
||||
}
|
||||
return findOne(id) != null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#count()
|
||||
*/
|
||||
public long count() {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#count()
|
||||
*/
|
||||
public long count() {
|
||||
|
||||
return template.getCollection(entityInformation.getCollectionName()).count();
|
||||
}
|
||||
return template.getCollection(entityInformation.getCollectionName()).count();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.Repository#delete(java.io.Serializable)
|
||||
*/
|
||||
public void delete(ID id) {
|
||||
delete(findOne(id));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#delete(java.lang.Object)
|
||||
*/
|
||||
public void delete(T entity) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.Repository#delete(java.io.Serializable)
|
||||
*/
|
||||
public void delete(ID id) {
|
||||
delete(findOne(id));
|
||||
}
|
||||
|
||||
template.remove(entityInformation.getCollectionName(), getIdQuery(entityInformation.getId(entity)), entity.getClass());
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#delete(java.lang.Object)
|
||||
*/
|
||||
public void delete(T entity) {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#delete(java.lang.Iterable)
|
||||
*/
|
||||
public void delete(Iterable<? extends T> entities) {
|
||||
template.remove(entityInformation.getCollectionName(), getIdQuery(entityInformation.getId(entity)),
|
||||
entity.getClass());
|
||||
}
|
||||
|
||||
for (T entity : entities) {
|
||||
delete(entity);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#delete(java.lang.Iterable)
|
||||
*/
|
||||
public void delete(Iterable<? extends T> entities) {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#deleteAll()
|
||||
*/
|
||||
public void deleteAll() {
|
||||
for (T entity : entities) {
|
||||
delete(entity);
|
||||
}
|
||||
}
|
||||
|
||||
template.remove(entityInformation.getCollectionName(), new Query());
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#deleteAll()
|
||||
*/
|
||||
public void deleteAll() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#findAll()
|
||||
*/
|
||||
public List<T> findAll() {
|
||||
template.remove(entityInformation.getCollectionName(), new Query());
|
||||
}
|
||||
|
||||
return findAll(new Query());
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#findAll()
|
||||
*/
|
||||
public List<T> findAll() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.PagingAndSortingRepository#findAll
|
||||
* (org.springframework.data.domain.Pageable)
|
||||
*/
|
||||
public Page<T> findAll(final Pageable pageable) {
|
||||
return findAll(new Query());
|
||||
}
|
||||
|
||||
Long count = count();
|
||||
List<T> list = findAll(QueryUtils.applyPagination(new Query(), pageable));
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.PagingAndSortingRepository#findAll
|
||||
* (org.springframework.data.domain.Pageable)
|
||||
*/
|
||||
public Page<T> findAll(final Pageable pageable) {
|
||||
|
||||
return new PageImpl<T>(list, pageable, count);
|
||||
}
|
||||
Long count = count();
|
||||
List<T> list = findAll(QueryUtils.applyPagination(new Query(), pageable));
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.PagingAndSortingRepository#findAll
|
||||
* (org.springframework.data.domain.Sort)
|
||||
*/
|
||||
public List<T> findAll(final Sort sort) {
|
||||
return new PageImpl<T>(list, pageable, count);
|
||||
}
|
||||
|
||||
return findAll(QueryUtils.applySorting(new Query(), sort));
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.PagingAndSortingRepository#findAll
|
||||
* (org.springframework.data.domain.Sort)
|
||||
*/
|
||||
public List<T> findAll(final Sort sort) {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#findAll(java.lang.Iterable
|
||||
* )
|
||||
*/
|
||||
public List<T> findAll(Iterable<ID> ids) {
|
||||
return findAll(QueryUtils.applySorting(new Query(), sort));
|
||||
}
|
||||
|
||||
Query query = null;
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#findAll(java.lang.Iterable
|
||||
* )
|
||||
*/
|
||||
public List<T> findAll(Iterable<ID> ids) {
|
||||
|
||||
for (ID id : ids) {
|
||||
if (query == null) {
|
||||
query = getIdQuery(id);
|
||||
} else {
|
||||
query = new Query().or(getIdQuery(id));
|
||||
}
|
||||
}
|
||||
Query query = null;
|
||||
|
||||
return findAll(query);
|
||||
}
|
||||
for (ID id : ids) {
|
||||
if (query == null) {
|
||||
query = getIdQuery(id);
|
||||
} else {
|
||||
query = new Query().or(getIdQuery(id));
|
||||
}
|
||||
}
|
||||
|
||||
private List<T> findAll(Query query) {
|
||||
return findAll(query);
|
||||
}
|
||||
|
||||
if (query == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
private List<T> findAll(Query query) {
|
||||
|
||||
return template.find(entityInformation.getCollectionName(), query, entityInformation.getJavaType());
|
||||
}
|
||||
if (query == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link MongoOperations} instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected MongoOperations getMongoOperations() {
|
||||
return template.find(entityInformation.getCollectionName(), query, entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
return this.template;
|
||||
}
|
||||
/**
|
||||
* Returns the underlying {@link MongoOperations} instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected MongoOperations getMongoOperations() {
|
||||
|
||||
/**
|
||||
* @return the entityInformation
|
||||
*/
|
||||
protected MongoEntityInformation<T, ID> getEntityInformation() {
|
||||
return this.template;
|
||||
}
|
||||
|
||||
return entityInformation;
|
||||
}
|
||||
/**
|
||||
* @return the entityInformation
|
||||
*/
|
||||
protected MongoEntityInformation<T, ID> getEntityInformation() {
|
||||
|
||||
return entityInformation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,79 +27,79 @@ import org.springframework.data.document.mongodb.query.Query;
|
||||
|
||||
/**
|
||||
* Query to use a plain JSON String to create the {@link Query} to actually execute.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
|
||||
private static final Pattern PLACEHOLDER = Pattern.compile("\\?(\\d+)");
|
||||
private static final Log LOG = LogFactory.getLog(StringBasedMongoQuery.class);
|
||||
private static final Pattern PLACEHOLDER = Pattern.compile("\\?(\\d+)");
|
||||
private static final Log LOG = LogFactory.getLog(StringBasedMongoQuery.class);
|
||||
|
||||
private final String query;
|
||||
private final String fieldSpec;
|
||||
private final String query;
|
||||
private final String fieldSpec;
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringBasedMongoQuery}.
|
||||
*
|
||||
* @param method
|
||||
* @param template
|
||||
*/
|
||||
public StringBasedMongoQuery(MongoQueryMethod method, MongoTemplate template) {
|
||||
super(method, template);
|
||||
this.query = method.getAnnotatedQuery();
|
||||
this.fieldSpec = method.getFieldSpecification();
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link StringBasedMongoQuery}.
|
||||
*
|
||||
* @param method
|
||||
* @param template
|
||||
*/
|
||||
public StringBasedMongoQuery(MongoQueryMethod method, MongoTemplate template) {
|
||||
super(method, template);
|
||||
this.query = method.getAnnotatedQuery();
|
||||
this.fieldSpec = method.getFieldSpecification();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.AbstractMongoQuery#createQuery(org.springframework.data.
|
||||
* repository.query.SimpleParameterAccessor, org.springframework.data.document.mongodb.support.convert.MongoConverter)
|
||||
*/
|
||||
@Override
|
||||
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.document.mongodb.repository.AbstractMongoQuery#createQuery(org.springframework.data.
|
||||
* repository.query.SimpleParameterAccessor, org.springframework.data.document.mongodb.support.convert.MongoConverter)
|
||||
*/
|
||||
@Override
|
||||
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
||||
|
||||
String queryString = replacePlaceholders(query, accessor);
|
||||
String queryString = replacePlaceholders(query, accessor);
|
||||
|
||||
Query query = null;
|
||||
Query query = null;
|
||||
|
||||
if (fieldSpec != null) {
|
||||
String fieldString = replacePlaceholders(fieldSpec, accessor);
|
||||
query = new BasicQuery(queryString, fieldString);
|
||||
} else {
|
||||
query = new BasicQuery(queryString);
|
||||
}
|
||||
if (fieldSpec != null) {
|
||||
String fieldString = replacePlaceholders(fieldSpec, accessor);
|
||||
query = new BasicQuery(queryString, fieldString);
|
||||
} else {
|
||||
query = new BasicQuery(queryString);
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format("Created query {}", query.getQueryObject()));
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format("Created query {}", query.getQueryObject()));
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
private String replacePlaceholders(String input, ConvertingParameterAccessor accessor) {
|
||||
private String replacePlaceholders(String input, ConvertingParameterAccessor accessor) {
|
||||
|
||||
Matcher matcher = PLACEHOLDER.matcher(input);
|
||||
String result = input;
|
||||
Matcher matcher = PLACEHOLDER.matcher(input);
|
||||
String result = input;
|
||||
|
||||
while (matcher.find()) {
|
||||
String group = matcher.group();
|
||||
int index = Integer.parseInt(matcher.group(1));
|
||||
result = input.replace(group, getParameterWithIndex(accessor, index));
|
||||
}
|
||||
while (matcher.find()) {
|
||||
String group = matcher.group();
|
||||
int index = Integer.parseInt(matcher.group(1));
|
||||
result = input.replace(group, getParameterWithIndex(accessor, index));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getParameterWithIndex(ConvertingParameterAccessor accessor, int index) {
|
||||
Object parameter = accessor.getBindableValue(index);
|
||||
if (parameter instanceof String || parameter.getClass().isEnum()) {
|
||||
return String.format("\"%s\"", parameter);
|
||||
} else if (parameter instanceof ObjectId) {
|
||||
return String.format("{ '$oid' : '%s' }", parameter);
|
||||
}
|
||||
private String getParameterWithIndex(ConvertingParameterAccessor accessor, int index) {
|
||||
Object parameter = accessor.getBindableValue(index);
|
||||
if (parameter instanceof String || parameter.getClass().isEnum()) {
|
||||
return String.format("\"%s\"", parameter);
|
||||
} else if (parameter instanceof ObjectId) {
|
||||
return String.format("{ '$oid' : '%s' }", parameter);
|
||||
}
|
||||
|
||||
return parameter.toString();
|
||||
}
|
||||
return parameter.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
* MongoDB specific repository implementation.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb.repository;
|
||||
|
||||
|
||||
@@ -26,25 +26,23 @@ import com.mongodb.Mongo;
|
||||
@Configuration
|
||||
public class GeoSpatialAppConfig extends AbstractMongoConfiguration {
|
||||
|
||||
@Bean
|
||||
public Mongo mongo() throws Exception {
|
||||
return new Mongo("localhost");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MongoTemplate mongoTemplate() throws Exception {
|
||||
return new MongoTemplate(mongo(), "geospatial", mappingMongoConverter());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoggingEventListener<MongoMappingEvent> mappingEventsListener() {
|
||||
return new LoggingEventListener<MongoMappingEvent>();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Mongo mongo() throws Exception {
|
||||
return new Mongo("localhost");
|
||||
}
|
||||
|
||||
public String getMappingBasePackage() {
|
||||
return "org.springframework.data.document.mongodb";
|
||||
}
|
||||
@Bean
|
||||
public MongoTemplate mongoTemplate() throws Exception {
|
||||
return new MongoTemplate(mongo(), "geospatial", mappingMongoConverter());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoggingEventListener<MongoMappingEvent> mappingEventsListener() {
|
||||
return new LoggingEventListener<MongoMappingEvent>();
|
||||
}
|
||||
|
||||
public String getMappingBasePackage() {
|
||||
return "org.springframework.data.document.mongodb";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,137 +51,134 @@ import com.mongodb.DBObject;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* Modified from https://github.com/deftlabs/mongo-java-geospatial-example
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class GeoSpatialTests {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(GeoSpatialTests.class);
|
||||
private final String[] collectionsToDrop = new String[]{"newyork"};
|
||||
private static final Log LOGGER = LogFactory.getLog(GeoSpatialTests.class);
|
||||
private final String[] collectionsToDrop = new String[] { "newyork" };
|
||||
|
||||
ApplicationContext applicationContext;
|
||||
MongoTemplate template;
|
||||
ServerInfo serverInfo;
|
||||
|
||||
ExpressionParser parser;
|
||||
ApplicationContext applicationContext;
|
||||
MongoTemplate template;
|
||||
ServerInfo serverInfo;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
Mongo mongo = new Mongo();
|
||||
serverInfo = new ServerInfo(mongo);
|
||||
DB db = mongo.getDB("geospatial");
|
||||
for (String coll : collectionsToDrop) {
|
||||
db.getCollection(coll).drop();
|
||||
}
|
||||
applicationContext = new AnnotationConfigApplicationContext(GeoSpatialAppConfig.class);
|
||||
template = applicationContext.getBean(MongoTemplate.class);
|
||||
template.setWriteConcern(WriteConcern.FSYNC_SAFE);
|
||||
template.ensureIndex(Venue.class, new GeospatialIndex("location"));
|
||||
indexCreated();
|
||||
addVenues();
|
||||
parser = new SpelExpressionParser();
|
||||
}
|
||||
ExpressionParser parser;
|
||||
|
||||
private void addVenues() {
|
||||
|
||||
template.insert(new Venue("Penn Station", -73.99408, 40.75057));
|
||||
template.insert(new Venue("10gen Office", -73.99171, 40.738868));
|
||||
template.insert(new Venue("Flatiron Building", -73.988135, 40.741404));
|
||||
template.insert(new Venue("Players Club", -73.997812, 40.739128));
|
||||
template.insert(new Venue("City Bakery ", -73.992491, 40.738673));
|
||||
template.insert(new Venue("Splash Bar", -73.992491, 40.738673));
|
||||
template.insert(new Venue("Momofuku Milk Bar", -73.985839, 40.731698));
|
||||
template.insert(new Venue("Shake Shack", -73.98820, 40.74164));
|
||||
template.insert(new Venue("Penn Station", -73.99408, 40.75057));
|
||||
template.insert(new Venue("Empire State Building", -73.98602, 40.74894));
|
||||
//template.insert(new Venue("Washington Square Park", -73.99756, 40.73083));
|
||||
template.insert(new Venue("Ulaanbaatar, Mongolia", 106.9154, 47.9245));
|
||||
template.insert(new Venue("Maplewood, NJ", -74.2713, 40.73137));
|
||||
}
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
Mongo mongo = new Mongo();
|
||||
serverInfo = new ServerInfo(mongo);
|
||||
DB db = mongo.getDB("geospatial");
|
||||
for (String coll : collectionsToDrop) {
|
||||
db.getCollection(coll).drop();
|
||||
}
|
||||
applicationContext = new AnnotationConfigApplicationContext(GeoSpatialAppConfig.class);
|
||||
template = applicationContext.getBean(MongoTemplate.class);
|
||||
template.setWriteConcern(WriteConcern.FSYNC_SAFE);
|
||||
template.ensureIndex(Venue.class, new GeospatialIndex("location"));
|
||||
indexCreated();
|
||||
addVenues();
|
||||
parser = new SpelExpressionParser();
|
||||
}
|
||||
|
||||
/*
|
||||
public void geoNear() {
|
||||
GeoNearResult<Venue> geoNearResult = template.geoNear(new Query(Criteria.where("type").is("Office")), Venue.class,
|
||||
GeoNearCriteria.near(2,3).num(10).maxDistance(10).distanceMultiplier(10).spherical(true));
|
||||
}*/
|
||||
private void addVenues() {
|
||||
|
||||
@Test
|
||||
public void withinCenter() {
|
||||
|
||||
Circle circle = new Circle(-73.99171, 40.738868, 0.01);
|
||||
List<Venue> venues = template.find(new Query(Criteria.where("location").withinCenter(circle)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(7));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("run only on v 1.7.0 server or greater")
|
||||
public void withinCenterSphere() {
|
||||
Circle circle = new Circle(-73.99171, 40.738868, 0.003712240453784);
|
||||
List<Venue> venues = template.find(new Query(Criteria.where("location").withinCenterSphere(circle)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(11));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void withinBox() {
|
||||
Box box = new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404));
|
||||
//Box box = newBox.lowerLeft(x,y).upperRight(x,y);
|
||||
List<Venue> venues = template.find(new Query(Criteria.where("location").withinBox(box)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nearPoint() {
|
||||
Point point = new Point(-73.99171, 40.738868);
|
||||
List<Venue> venues = template.find(new Query(Criteria.where("location").near(point).maxDistance(0.01)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(7));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("run only on v 1.7.0 server or greater")
|
||||
public void nearSphere() {
|
||||
Point point = new Point(-73.99171, 40.738868);
|
||||
List<Venue> venues = template.find(new Query(Criteria.where("location").nearSphere(point).maxDistance(0.003712240453784)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(11));
|
||||
}
|
||||
|
||||
template.insert(new Venue("Penn Station", -73.99408, 40.75057));
|
||||
template.insert(new Venue("10gen Office", -73.99171, 40.738868));
|
||||
template.insert(new Venue("Flatiron Building", -73.988135, 40.741404));
|
||||
template.insert(new Venue("Players Club", -73.997812, 40.739128));
|
||||
template.insert(new Venue("City Bakery ", -73.992491, 40.738673));
|
||||
template.insert(new Venue("Splash Bar", -73.992491, 40.738673));
|
||||
template.insert(new Venue("Momofuku Milk Bar", -73.985839, 40.731698));
|
||||
template.insert(new Venue("Shake Shack", -73.98820, 40.74164));
|
||||
template.insert(new Venue("Penn Station", -73.99408, 40.75057));
|
||||
template.insert(new Venue("Empire State Building", -73.98602, 40.74894));
|
||||
// template.insert(new Venue("Washington Square Park", -73.99756, 40.73083));
|
||||
template.insert(new Venue("Ulaanbaatar, Mongolia", 106.9154, 47.9245));
|
||||
template.insert(new Venue("Maplewood, NJ", -74.2713, 40.73137));
|
||||
}
|
||||
|
||||
/*
|
||||
public void geoNear() {
|
||||
GeoNearResult<Venue> geoNearResult = template.geoNear(new Query(Criteria.where("type").is("Office")), Venue.class,
|
||||
GeoNearCriteria.near(2,3).num(10).maxDistance(10).distanceMultiplier(10).spherical(true));
|
||||
}*/
|
||||
|
||||
@Test
|
||||
public void searchAllData() {
|
||||
assertThat(template, notNullValue());
|
||||
Venue foundVenue = template.findOne(
|
||||
new Query(Criteria.where("name").is("Penn Station")), Venue.class);
|
||||
assertThat(foundVenue, notNullValue());
|
||||
List<Venue> venues = template.getCollection(Venue.class);
|
||||
assertThat(venues.size(), equalTo(12));
|
||||
Collection names = (Collection)parser.parseExpression("![name]").getValue(venues);
|
||||
assertThat(names.size(), equalTo(12));
|
||||
org.springframework.util.Assert.notEmpty(names);
|
||||
|
||||
}
|
||||
|
||||
public void indexCreated() {
|
||||
List<DBObject> indexInfo = getIndexInfo(Venue.class);
|
||||
LOGGER.debug(indexInfo);
|
||||
assertThat(indexInfo.size(), equalTo(2));
|
||||
assertThat(indexInfo.get(1).get("name").toString(), equalTo("location_2d"));
|
||||
assertThat(indexInfo.get(1).get("ns").toString(),
|
||||
equalTo("geospatial.newyork"));
|
||||
}
|
||||
@Test
|
||||
public void withinCenter() {
|
||||
|
||||
// TODO move to MongoAdmin
|
||||
public List<DBObject> getIndexInfo(Class clazz) {
|
||||
return template.execute(clazz, new CollectionCallback<List<DBObject>>() {
|
||||
Circle circle = new Circle(-73.99171, 40.738868, 0.01);
|
||||
List<Venue> venues = template.find(new Query(Criteria.where("location").withinCenter(circle)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(7));
|
||||
}
|
||||
|
||||
public List<DBObject> doInCollection(DBCollection collection)
|
||||
throws MongoException, DataAccessException {
|
||||
return collection.getIndexInfo();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("run only on v 1.7.0 server or greater")
|
||||
public void withinCenterSphere() {
|
||||
Circle circle = new Circle(-73.99171, 40.738868, 0.003712240453784);
|
||||
List<Venue> venues = template.find(new Query(Criteria.where("location").withinCenterSphere(circle)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(11));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withinBox() {
|
||||
Box box = new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404));
|
||||
// Box box = newBox.lowerLeft(x,y).upperRight(x,y);
|
||||
List<Venue> venues = template.find(new Query(Criteria.where("location").withinBox(box)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nearPoint() {
|
||||
Point point = new Point(-73.99171, 40.738868);
|
||||
List<Venue> venues = template
|
||||
.find(new Query(Criteria.where("location").near(point).maxDistance(0.01)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(7));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("run only on v 1.7.0 server or greater")
|
||||
public void nearSphere() {
|
||||
Point point = new Point(-73.99171, 40.738868);
|
||||
List<Venue> venues = template.find(
|
||||
new Query(Criteria.where("location").nearSphere(point).maxDistance(0.003712240453784)), Venue.class);
|
||||
assertThat(venues.size(), equalTo(11));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void searchAllData() {
|
||||
assertThat(template, notNullValue());
|
||||
Venue foundVenue = template.findOne(new Query(Criteria.where("name").is("Penn Station")), Venue.class);
|
||||
assertThat(foundVenue, notNullValue());
|
||||
List<Venue> venues = template.getCollection(Venue.class);
|
||||
assertThat(venues.size(), equalTo(12));
|
||||
Collection names = (Collection) parser.parseExpression("![name]").getValue(venues);
|
||||
assertThat(names.size(), equalTo(12));
|
||||
org.springframework.util.Assert.notEmpty(names);
|
||||
|
||||
}
|
||||
|
||||
public void indexCreated() {
|
||||
List<DBObject> indexInfo = getIndexInfo(Venue.class);
|
||||
LOGGER.debug(indexInfo);
|
||||
assertThat(indexInfo.size(), equalTo(2));
|
||||
assertThat(indexInfo.get(1).get("name").toString(), equalTo("location_2d"));
|
||||
assertThat(indexInfo.get(1).get("ns").toString(), equalTo("geospatial.newyork"));
|
||||
}
|
||||
|
||||
// TODO move to MongoAdmin
|
||||
public List<DBObject> getIndexInfo(Class clazz) {
|
||||
return template.execute(clazz, new CollectionCallback<List<DBObject>>() {
|
||||
|
||||
public List<DBObject> doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
return collection.getIndexInfo();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user