refactoring connection factory bean; adding exception translation hooks
This commit is contained in:
@@ -19,12 +19,11 @@ package org.springframework.datastore.document;
|
|||||||
|
|
||||||
public abstract class AbstractDocumentStoreTemplate<C> {
|
public abstract class AbstractDocumentStoreTemplate<C> {
|
||||||
|
|
||||||
|
public abstract C getConnection();
|
||||||
public abstract DocumentStoreConnectionFactory<C> getDocumentStoreConnectionFactory();
|
|
||||||
|
|
||||||
public <T> T execute(DocumentStoreConnectionCallback<C, T> action) {
|
public <T> T execute(DocumentStoreConnectionCallback<C, T> action) {
|
||||||
try {
|
try {
|
||||||
return action.doInConnection(getDocumentStoreConnectionFactory().getConnection());
|
return action.doInConnection(getConnection());
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new UncategorizedDocumentStoreException("Failure executing using datastore connection", e);
|
throw new UncategorizedDocumentStoreException("Failure executing using datastore connection", e);
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.datastore.document;
|
|
||||||
|
|
||||||
public interface DocumentStoreConnectionFactory<C> {
|
|
||||||
C getConnection();
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2010 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.datastore.document.couchdb;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.jcouchdb.db.Database;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.datastore.document.DocumentStoreConnectionFactory;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenient factory for configuring CouchDB.
|
|
||||||
*
|
|
||||||
* @author Thomas Risberg
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public class CouchDbConnectionFactory implements DocumentStoreConnectionFactory<Database>, InitializingBean {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logger, available to subclasses.
|
|
||||||
*/
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
|
||||||
|
|
||||||
private Database database;
|
|
||||||
private String host;
|
|
||||||
private String databaseName;
|
|
||||||
|
|
||||||
public CouchDbConnectionFactory() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CouchDbConnectionFactory(String host, String databaseName) {
|
|
||||||
super();
|
|
||||||
this.host = host;
|
|
||||||
this.databaseName = databaseName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CouchDbConnectionFactory(Database database) {
|
|
||||||
super();
|
|
||||||
this.database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDatabase(Database database) {
|
|
||||||
this.database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDatabaseName(String databaseName) {
|
|
||||||
this.databaseName = databaseName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHost(String host) {
|
|
||||||
this.host = host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSingleton() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
|
||||||
// apply defaults - convenient when used to configure for tests
|
|
||||||
// in an application context
|
|
||||||
if (database == null) {
|
|
||||||
if (databaseName == null) {
|
|
||||||
logger.warn("Property databaseName not specified. Using default name 'test'");
|
|
||||||
databaseName = "test";
|
|
||||||
}
|
|
||||||
if (host == null) {
|
|
||||||
logger.warn("Property host not specified. Using default 'localhost'");
|
|
||||||
database = new Database(host, databaseName);
|
|
||||||
}
|
|
||||||
database = new Database(host, databaseName);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logger.info("Using provided database configuration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Database getConnection() {
|
|
||||||
synchronized (this){
|
|
||||||
if (database == null) {
|
|
||||||
try {
|
|
||||||
afterPropertiesSet();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new CannotGetCouchDbConnectionException("Unable to connect to CouchDB", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return database;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -14,73 +14,63 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
package org.springframework.datastore.document.couchdb;
|
||||||
* Copyright 2010 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.datastore.document.mongodb;
|
import org.jcouchdb.db.Database;
|
||||||
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.datastore.document.DocumentStoreConnectionFactory;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
import com.mongodb.DB;
|
|
||||||
import com.mongodb.Mongo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenient factory for configuring MongoDB.
|
* Convenient factory for configuring MongoDB.
|
||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public class MongoDbConnectionFactory implements DocumentStoreConnectionFactory<DB>, InitializingBean {
|
public class CouchDbFactoryBean implements FactoryBean<Database>, InitializingBean,
|
||||||
|
PersistenceExceptionTranslator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger, available to subclasses.
|
* Logger, available to subclasses.
|
||||||
*/
|
*/
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private Mongo mongo;
|
private String host;
|
||||||
|
private Integer port;
|
||||||
private String databaseName;
|
private String databaseName;
|
||||||
|
|
||||||
public MongoDbConnectionFactory() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoDbConnectionFactory(String databaseName) {
|
|
||||||
super();
|
|
||||||
this.databaseName = databaseName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoDbConnectionFactory(Mongo mongo, String databaseName) {
|
|
||||||
super();
|
|
||||||
this.mongo = mongo;
|
|
||||||
this.databaseName = databaseName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMongo(Mongo mongo) {
|
|
||||||
this.mongo = mongo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDatabaseName(String databaseName) {
|
public void setDatabaseName(String databaseName) {
|
||||||
this.databaseName = databaseName;
|
this.databaseName = databaseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Database getObject() throws Exception {
|
||||||
|
Assert.hasText(host, "Host must not be empty");
|
||||||
|
Assert.hasText(databaseName, "Database name must not be empty");
|
||||||
|
if (port == null) {
|
||||||
|
return new Database(host, databaseName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new Database(host, port, databaseName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends Database> getObjectType() {
|
||||||
|
return Database.class;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSingleton() {
|
public boolean isSingleton() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -88,20 +78,19 @@ public class MongoDbConnectionFactory implements DocumentStoreConnectionFactory<
|
|||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
// apply defaults - convenient when used to configure for tests
|
// apply defaults - convenient when used to configure for tests
|
||||||
// in an application context
|
// in an application context
|
||||||
|
if (host == null) {
|
||||||
|
logger.warn("Property host not specified. Using default 'localhost'");
|
||||||
|
databaseName = "localhost";
|
||||||
|
}
|
||||||
if (databaseName == null) {
|
if (databaseName == null) {
|
||||||
logger.warn("Property databaseName not specified. Using default name 'test'");
|
logger.warn("Property databaseName not specified. Using default name 'test'");
|
||||||
databaseName = "test";
|
databaseName = "test";
|
||||||
}
|
}
|
||||||
if (mongo == null) {
|
|
||||||
logger.warn("Property mongo not specified. Using default configuration");
|
|
||||||
mongo = new Mongo();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DB getConnection() {
|
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||||
Assert.notNull(mongo, "Mongo must not be null");
|
logger.debug("Translating " + ex);
|
||||||
Assert.hasText(databaseName, "Database name must not be empty");
|
return CouchDbUtils.translateCouchExceptionIfPossible(ex);
|
||||||
return mongo.getDB(databaseName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.datastore.document.couchdb;
|
||||||
|
|
||||||
|
import org.jcouchdb.exception.CouchDBException;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.datastore.document.UncategorizedDocumentStoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class featuring helper methods for internal MongoDb classes.
|
||||||
|
*
|
||||||
|
* <p>Mainly intended for internal use within the framework.
|
||||||
|
*
|
||||||
|
* @author Thomas Risberg
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
public class CouchDbUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the given runtime exception to an appropriate exception from the
|
||||||
|
* <code>org.springframework.dao</code> hierarchy.
|
||||||
|
* Return 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
|
||||||
|
* @return the corresponding DataAccessException instance,
|
||||||
|
* or <code>null</code> if the exception should not be translated
|
||||||
|
*/
|
||||||
|
public static DataAccessException translateCouchExceptionIfPossible(RuntimeException ex) {
|
||||||
|
|
||||||
|
// Check for well-known MongoException subclasses.
|
||||||
|
|
||||||
|
// All other MongoExceptions
|
||||||
|
if (ex instanceof CouchDBException) {
|
||||||
|
return new UncategorizedDocumentStoreException(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,11 +21,10 @@ import org.jcouchdb.db.Database;
|
|||||||
import org.jcouchdb.document.BaseDocument;
|
import org.jcouchdb.document.BaseDocument;
|
||||||
import org.springframework.datastore.document.AbstractDocumentStoreTemplate;
|
import org.springframework.datastore.document.AbstractDocumentStoreTemplate;
|
||||||
import org.springframework.datastore.document.DocumentSource;
|
import org.springframework.datastore.document.DocumentSource;
|
||||||
import org.springframework.datastore.document.DocumentStoreConnectionFactory;
|
|
||||||
|
|
||||||
public class CouchTemplate extends AbstractDocumentStoreTemplate<Database> {
|
public class CouchTemplate extends AbstractDocumentStoreTemplate<Database> {
|
||||||
|
|
||||||
private DocumentStoreConnectionFactory<Database> connectionFactory;
|
private Database database;
|
||||||
|
|
||||||
public CouchTemplate() {
|
public CouchTemplate() {
|
||||||
super();
|
super();
|
||||||
@@ -33,22 +32,22 @@ import org.springframework.datastore.document.DocumentStoreConnectionFactory;
|
|||||||
|
|
||||||
public CouchTemplate(String host, String databaseName) {
|
public CouchTemplate(String host, String databaseName) {
|
||||||
super();
|
super();
|
||||||
connectionFactory = new CouchDbConnectionFactory(host, databaseName);
|
database = new Database(host, databaseName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CouchTemplate(CouchDbConnectionFactory mcf) {
|
public CouchTemplate(Database database) {
|
||||||
super();
|
super();
|
||||||
connectionFactory = mcf;
|
this.database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(DocumentSource<BaseDocument> documentSource) {
|
public void save(DocumentSource<BaseDocument> documentSource) {
|
||||||
BaseDocument d = documentSource.getDocument();
|
BaseDocument d = documentSource.getDocument();
|
||||||
getDocumentStoreConnectionFactory().getConnection().createDocument(d);
|
getConnection().createDocument(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DocumentStoreConnectionFactory<Database> getDocumentStoreConnectionFactory() {
|
public Database getConnection() {
|
||||||
return connectionFactory;
|
return database;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,13 +27,9 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.BeanWrapper;
|
import org.springframework.beans.BeanWrapper;
|
||||||
import org.springframework.beans.NotReadablePropertyException;
|
import org.springframework.beans.NotReadablePropertyException;
|
||||||
import org.springframework.beans.NotWritablePropertyException;
|
|
||||||
import org.springframework.beans.PropertyAccessorFactory;
|
import org.springframework.beans.PropertyAccessorFactory;
|
||||||
import org.springframework.beans.TypeMismatchException;
|
|
||||||
import org.springframework.dao.DataRetrievalFailureException;
|
import org.springframework.dao.DataRetrievalFailureException;
|
||||||
import org.springframework.datastore.document.DocumentMapper;
|
|
||||||
import org.springframework.datastore.document.DocumentSource;
|
import org.springframework.datastore.document.DocumentSource;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
@@ -67,6 +63,7 @@ public class MongoBeanPropertyDocumentSource implements DocumentSource<DBObject>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
public DBObject getDocument() {
|
public DBObject getDocument() {
|
||||||
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this.source);
|
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this.source);
|
||||||
DBObject dbo = new BasicDBObject();
|
DBObject dbo = new BasicDBObject();
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ package org.springframework.datastore.document.mongodb;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import com.mongodb.DB;
|
import com.mongodb.DB;
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
@@ -31,25 +34,39 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public class MongoDbFactoryBean implements FactoryBean<DB>, InitializingBean {
|
public class MongoDbFactoryBean implements FactoryBean<DB>, InitializingBean,
|
||||||
|
PersistenceExceptionTranslator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger, available to subclasses.
|
* Logger, available to subclasses.
|
||||||
*/
|
*/
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private MongoDbConnectionFactory mcf = new MongoDbConnectionFactory();
|
private Mongo mongo;
|
||||||
|
private String host;
|
||||||
|
private Integer port;
|
||||||
|
private String databaseName;
|
||||||
|
|
||||||
public void setMongo(Mongo mongo) {
|
public void setMongo(Mongo mongo) {
|
||||||
this.mcf.setMongo(mongo);
|
this.mongo = mongo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDatabaseName(String databaseName) {
|
public void setDatabaseName(String databaseName) {
|
||||||
this.mcf.setDatabaseName(databaseName);
|
this.databaseName = databaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DB getObject() throws Exception {
|
public DB getObject() throws Exception {
|
||||||
return mcf.getConnection();
|
Assert.notNull(mongo, "Mongo must not be null");
|
||||||
|
Assert.hasText(databaseName, "Database name must not be empty");
|
||||||
|
return mongo.getDB(databaseName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<? extends DB> getObjectType() {
|
public Class<? extends DB> getObjectType() {
|
||||||
@@ -61,7 +78,31 @@ public class MongoDbFactoryBean implements FactoryBean<DB>, InitializingBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
this.mcf.afterPropertiesSet();
|
// apply defaults - convenient when used to configure for tests
|
||||||
|
// in an application context
|
||||||
|
if (databaseName == null) {
|
||||||
|
logger.warn("Property databaseName not specified. Using default name 'test'");
|
||||||
|
databaseName = "test";
|
||||||
|
}
|
||||||
|
if (mongo == null) {
|
||||||
|
logger.warn("Property mongo not specified. Using default configuration");
|
||||||
|
if (host == null) {
|
||||||
|
mongo = new Mongo();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (port == null) {
|
||||||
|
mongo = new Mongo(host);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mongo = new Mongo(host, port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||||
|
logger.debug("Translating " + ex);
|
||||||
|
return MongoDbUtils.translateMongoExceptionIfPossible(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.datastore.document.mongodb;
|
||||||
|
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.datastore.document.UncategorizedDocumentStoreException;
|
||||||
|
|
||||||
|
import com.mongodb.MongoException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class featuring helper methods for internal MongoDb classes.
|
||||||
|
*
|
||||||
|
* <p>Mainly intended for internal use within the framework.
|
||||||
|
*
|
||||||
|
* @author Thomas Risberg
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
public class MongoDbUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the given runtime exception to an appropriate exception from the
|
||||||
|
* <code>org.springframework.dao</code> hierarchy.
|
||||||
|
* Return 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
|
||||||
|
* @return the corresponding DataAccessException instance,
|
||||||
|
* or <code>null</code> if the exception should not be translated
|
||||||
|
*/
|
||||||
|
public static DataAccessException translateMongoExceptionIfPossible(RuntimeException ex) {
|
||||||
|
|
||||||
|
// Check for well-known MongoException subclasses.
|
||||||
|
|
||||||
|
// All other MongoExceptions
|
||||||
|
if (ex instanceof MongoException) {
|
||||||
|
return new UncategorizedDocumentStoreException(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -25,42 +25,29 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
|
|||||||
import org.springframework.datastore.document.AbstractDocumentStoreTemplate;
|
import org.springframework.datastore.document.AbstractDocumentStoreTemplate;
|
||||||
import org.springframework.datastore.document.DocumentMapper;
|
import org.springframework.datastore.document.DocumentMapper;
|
||||||
import org.springframework.datastore.document.DocumentSource;
|
import org.springframework.datastore.document.DocumentSource;
|
||||||
import org.springframework.datastore.document.DocumentStoreConnectionFactory;
|
|
||||||
|
|
||||||
import com.mongodb.CommandResult;
|
import com.mongodb.CommandResult;
|
||||||
import com.mongodb.DB;
|
import com.mongodb.DB;
|
||||||
import com.mongodb.DBCollection;
|
import com.mongodb.DBCollection;
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
import com.mongodb.Mongo;
|
|
||||||
import com.mongodb.MongoException;
|
import com.mongodb.MongoException;
|
||||||
import com.mongodb.WriteResult;
|
import com.mongodb.WriteResult;
|
||||||
|
|
||||||
public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> {
|
public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> {
|
||||||
|
|
||||||
private DocumentStoreConnectionFactory<DB> connectionFactory;
|
private DB db;
|
||||||
|
|
||||||
public MongoTemplate() {
|
// public MongoTemplate() {
|
||||||
|
// super();
|
||||||
|
// }
|
||||||
|
|
||||||
|
public MongoTemplate(DB db) {
|
||||||
super();
|
super();
|
||||||
}
|
this.db = db;
|
||||||
|
|
||||||
public MongoTemplate(Mongo mongo, String databaseName) {
|
|
||||||
super();
|
|
||||||
connectionFactory = new MongoDbConnectionFactory(mongo, databaseName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoTemplate(MongoDbConnectionFactory mcf) {
|
|
||||||
super();
|
|
||||||
connectionFactory = mcf;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DocumentStoreConnectionFactory<DB> getDocumentStoreConnectionFactory() {
|
|
||||||
return connectionFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(String command) {
|
public void execute(String command) {
|
||||||
DB db = getDocumentStoreConnectionFactory().getConnection();
|
CommandResult cr = getConnection().command(command);
|
||||||
CommandResult cr = db.command(command);
|
|
||||||
String err = cr.getErrorMessage();
|
String err = cr.getErrorMessage();
|
||||||
if (err != null) {
|
if (err != null) {
|
||||||
throw new InvalidDataAccessApiUsageException("Command execution of " +
|
throw new InvalidDataAccessApiUsageException("Command execution of " +
|
||||||
@@ -69,9 +56,7 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void execute(DocumentSource<DBObject> command) {
|
public void execute(DocumentSource<DBObject> command) {
|
||||||
CommandResult cr = getDocumentStoreConnectionFactory()
|
CommandResult cr = getConnection().command(command.getDocument());
|
||||||
.getConnection()
|
|
||||||
.command(command.getDocument());
|
|
||||||
String err = cr.getErrorMessage();
|
String err = cr.getErrorMessage();
|
||||||
if (err != null) {
|
if (err != null) {
|
||||||
throw new InvalidDataAccessApiUsageException("Command execution of " +
|
throw new InvalidDataAccessApiUsageException("Command execution of " +
|
||||||
@@ -80,18 +65,15 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void createCollection(String collectionName, DocumentSource<DBObject> documentSource) {
|
public void createCollection(String collectionName, DocumentSource<DBObject> documentSource) {
|
||||||
DB db = getDocumentStoreConnectionFactory().getConnection();
|
|
||||||
try {
|
try {
|
||||||
db.createCollection(collectionName, documentSource.getDocument());
|
getConnection().createCollection(collectionName, documentSource.getDocument());
|
||||||
} catch (MongoException e) {
|
} catch (MongoException e) {
|
||||||
throw new InvalidDataAccessApiUsageException("Error creating collection " + collectionName + ": " + e.getMessage(), e);
|
throw new InvalidDataAccessApiUsageException("Error creating collection " + collectionName + ": " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dropCollection(String collectionName) {
|
public void dropCollection(String collectionName) {
|
||||||
getDocumentStoreConnectionFactory()
|
getConnection().getCollection(collectionName)
|
||||||
.getConnection()
|
|
||||||
.getCollection(collectionName)
|
|
||||||
.drop();
|
.drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,10 +84,9 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> {
|
|||||||
|
|
||||||
public void save(String collectionName, DocumentSource<DBObject> documentSource) {
|
public void save(String collectionName, DocumentSource<DBObject> documentSource) {
|
||||||
DBObject dbDoc = documentSource.getDocument();
|
DBObject dbDoc = documentSource.getDocument();
|
||||||
DB db = getDocumentStoreConnectionFactory().getConnection();
|
|
||||||
WriteResult wr = null;
|
WriteResult wr = null;
|
||||||
try {
|
try {
|
||||||
wr = db.getCollection(collectionName).save(dbDoc);
|
wr = getConnection().getCollection(collectionName).save(dbDoc);
|
||||||
} catch (MongoException e) {
|
} catch (MongoException e) {
|
||||||
throw new DataRetrievalFailureException(wr.getLastError().getErrorMessage(), e);
|
throw new DataRetrievalFailureException(wr.getLastError().getErrorMessage(), e);
|
||||||
}
|
}
|
||||||
@@ -118,12 +99,20 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate<DB> {
|
|||||||
|
|
||||||
public <T> List<T> queryForCollection(String collectionName, DocumentMapper<DBObject, T> mapper) {
|
public <T> List<T> queryForCollection(String collectionName, DocumentMapper<DBObject, T> mapper) {
|
||||||
List<T> results = new ArrayList<T>();
|
List<T> results = new ArrayList<T>();
|
||||||
DB db = getDocumentStoreConnectionFactory().getConnection();
|
DBCollection collection = getConnection().getCollection(collectionName);
|
||||||
DBCollection collection = db.getCollection(collectionName);
|
|
||||||
for (DBObject dbo : collection.find()) {
|
for (DBObject dbo : collection.find()) {
|
||||||
results.add(mapper.mapDocument(dbo));
|
results.add(mapper.mapDocument(dbo));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RuntimeException translateIfNecessary(RuntimeException ex) {
|
||||||
|
return MongoDbUtils.translateMongoExceptionIfPossible(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DB getConnection() {
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user