Some little tidy-ups on the codebase.

-=david=-
This commit is contained in:
David Harrigan
2013-10-12 21:36:15 +01:00
committed by Michael Nitschinger
parent d1779a5d73
commit 47a0125642
3 changed files with 116 additions and 117 deletions

View File

@@ -32,7 +32,7 @@ import java.util.concurrent.CancellationException;
/**
* Simple {@link PersistenceExceptionTranslator} for Couchbase.
*
* <p/>
* 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.
@@ -45,20 +45,21 @@ public class CouchbaseExceptionTranslator implements PersistenceExceptionTransla
* Translate Couchbase specific exceptions to spring exceptions if possible.
*
* @param ex the exception to translate.
*
* @return the translated exception or null.
*/
@Override
public final DataAccessException translateExceptionIfPossible(final RuntimeException ex) {
@Override
public final DataAccessException translateExceptionIfPossible(final RuntimeException ex) {
if (ex instanceof ConnectionException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof ObservedException
|| ex instanceof ObservedTimeoutException
|| ex instanceof ObservedModifiedException) {
return new DataIntegrityViolationException(ex.getMessage(), ex);
}
if (ex instanceof ConnectionException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof ObservedException
|| ex instanceof ObservedTimeoutException
|| ex instanceof ObservedModifiedException) {
return new DataIntegrityViolationException(ex.getMessage(), ex);
}
if (ex instanceof CancellationException) {
throw new OperationCancellationException(ex.getMessage(), ex);
@@ -67,8 +68,9 @@ public class CouchbaseExceptionTranslator implements PersistenceExceptionTransla
if (ex instanceof InvalidViewException) {
throw new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
}
return null;
}
// Unable to translate exception, therefore just throw the original!
throw ex;
}
}

View File

@@ -33,79 +33,80 @@ public interface CouchbaseOperations {
/**
* Save the given object.
*
* <p/>
* <p>When the document already exists (specified by its unique id), then it will be overriden. Otherwise it will be
* created.</p>
*
* @param objectToSave the object to store in the bucket.
*/
void save(Object objectToSave);
/**
* Save a list of objects.
*
* <p/>
* <p>When one of the documents already exists (specified by its unique id), then it will be overriden. Otherwise it
* will be created.</p>
*
* @param batchToSave the list of objects to store in the bucket.
*/
void save(Collection<? extends Object> batchToSave);
void save(Collection<?> batchToSave);
/**
* Insert the given object.
*
* <p/>
* <p>When the document already exists (specified by its unique id), then it will not be overriden. Use the
* {@link CouchbaseOperations#save} method for this task.</p>
*
* @param objectToSave the object to add to the bucket.
*/
void insert(Object objectToSave);
/**
* Insert a list of objects.
*
* <p/>
* <p>When one of the documents already exists (specified by its unique id), then it will not be overriden. Use the
* {@link CouchbaseOperations#save} method for this.</p>
*
* @param batchToSave the list of objects to add to the bucket.
*/
void insert(Collection<? extends Object> batchToSave);
void insert(Collection<?> batchToSave);
/**
* Update the given object.
*
* <p/>
* <p>When the document does not exist (specified by its unique id) it will not be created. Use the
* {@link CouchbaseOperations#save} method for this.</p>
*
* @param objectToSave the object to add to the bucket.
*/
void update(Object objectToSave);
/**
* Insert a list of objects.
*
* <p/>
* <p>If one of the documents does not exist (specified by its unique id), then it will not be created. Use the
* {@link CouchbaseOperations#save} method for this.</p>
*
* @param batchToSave the list of objects to add to the bucket.
*/
void update(Collection<? extends Object> batchToSave);
void update(Collection<?> batchToSave);
/**
* Find an object by its given Id and map it to the corresponding entity.
*
* @param id the unique ID of the document.
* @param entityClass the entity to map to.
*
* @return returns the found object or null otherwise.
*/
<T> T findById(String id, Class<T> entityClass);
/**
* Query a View for a list of documents of type T.
*
* <p/>
* <p>There is no need to {@link Query#setIncludeDocs(boolean)} explicitely, because it will be set to true all the
* time. It is valid to pass in a empty constructed {@link Query} object.</p>
*
* <p/>
* <p>This method does not work with reduced views, because they by design do not contain references to original
* objects. Use the provided {@link #queryView} method for more flexibility and direct access.</p>
*
@@ -113,6 +114,7 @@ public interface CouchbaseOperations {
* @param view the name of the viewName.
* @param query the Query object to customize the viewName query.
* @param entityClass the entity to map to.
*
* @return the converted collection
*/
<T> List<T> findByView(String design, String view, Query query, Class<T> entityClass);
@@ -120,17 +122,16 @@ public interface CouchbaseOperations {
/**
* Query a View with direct access to the {@link ViewResponse}.
*
* <p>This method is available to ease the working with views by still wrapping exceptions into the Spring
* infrastructure.</p>
*
* <p>It is especially needed if you want to run reduced viewName queries, because they can't be mapped onto entities
* directly.</p>
*
* @param design the name of the designDocument document.
* @param view the name of the viewName.
* @param query the Query object to customize the viewName query.
* @return
*
* @return ViewResponse containing the results of the query.
*/
ViewResponse queryView(String design, String view, Query query);
@@ -138,13 +139,14 @@ public interface CouchbaseOperations {
* Checks if the given document exists.
*
* @param id the unique ID of the document.
*
* @return whether the document could be found or not.
*/
boolean exists(String id);
/**
* Remove the given object from the bucket by id.
*
* <p/>
* If the object is a String, it will be treated as the document key
* directly.
*
@@ -157,22 +159,24 @@ public interface CouchbaseOperations {
*
* @param batchToRemove the list of Objects to remove.
*/
void remove(Collection<? extends Object> batchToRemove);
void remove(Collection<?> batchToRemove);
/**
* Executes a BucketCallback translating any exceptions as necessary.
*
* <p/>
* Allows for returning a result object, that is a domain object or a collection of domain objects.
*
* @param action the action to execute in the callback.
* @param <T> the return type.
* @return
*
* @return the return type.
*/
<T> T execute(BucketCallback<T> action);
/**
* Returns the underlying {@link CouchbaseConverter}.
* @return
*
* @return CouchbaseConverter.
*/
CouchbaseConverter getConverter();

View File

@@ -26,11 +26,20 @@ import org.springframework.dao.QueryTimeoutException;
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
import org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService;
import org.springframework.data.couchbase.core.convert.translation.TranslationService;
import org.springframework.data.couchbase.core.mapping.*;
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
import org.springframework.data.couchbase.core.mapping.CouchbaseStorable;
import org.springframework.data.mapping.context.MappingContext;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
@@ -41,36 +50,32 @@ public class CouchbaseTemplate implements CouchbaseOperations {
private CouchbaseClient client;
private CouchbaseConverter couchbaseConverter;
protected final MappingContext<? extends CouchbasePersistentEntity<?>,
CouchbasePersistentProperty> mappingContext;
protected final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext;
private static final Collection<String> ITERABLE_CLASSES;
private final CouchbaseExceptionTranslator exceptionTranslator =
new CouchbaseExceptionTranslator();
private final TranslationService<Object> translationService;
static {
Set<String> iterableClasses = new HashSet<String>();
iterableClasses.add(List.class.getName());
iterableClasses.add(Collection.class.getName());
iterableClasses.add(Iterator.class.getName());
ITERABLE_CLASSES = Collections.unmodifiableCollection(iterableClasses);
}
private final CouchbaseExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator();
private final JacksonTranslationService translationService;
static {
final Set<String> iterableClasses = new HashSet<String>();
iterableClasses.add(List.class.getName());
iterableClasses.add(Collection.class.getName());
iterableClasses.add(Iterator.class.getName());
ITERABLE_CLASSES = Collections.unmodifiableCollection(iterableClasses);
}
public CouchbaseTemplate(final CouchbaseClient client) {
this(client, null);
}
public CouchbaseTemplate(final CouchbaseClient client,
final CouchbaseConverter converter) {
public CouchbaseTemplate(final CouchbaseClient client, final CouchbaseConverter converter) {
this.client = client;
couchbaseConverter = converter == null ? getDefaultConverter(client) : converter;
couchbaseConverter = converter == null ? getDefaultConverter() : converter;
mappingContext = couchbaseConverter.getMappingContext();
translationService = new JacksonTranslationService();
}
private CouchbaseConverter getDefaultConverter(final CouchbaseClient client) {
MappingCouchbaseConverter converter = new MappingCouchbaseConverter(
new CouchbaseMappingContext());
private CouchbaseConverter getDefaultConverter() {
final MappingCouchbaseConverter converter = new MappingCouchbaseConverter(new CouchbaseMappingContext());
converter.afterPropertiesSet();
return converter;
}
@@ -84,7 +89,7 @@ public class CouchbaseTemplate implements CouchbaseOperations {
}
public final void insert(final Object objectToSave) {
ensureNotIterable(objectToSave);
ensureNotIterable(objectToSave);
final CouchbaseDocument converted = new CouchbaseDocument();
couchbaseConverter.write(objectToSave, converted);
@@ -96,16 +101,15 @@ public class CouchbaseTemplate implements CouchbaseOperations {
}
});
}
public final void insert(final Collection<? extends Object> batchToSave) {
Iterator<? extends Object> iter = batchToSave.iterator();
while (iter.hasNext()) {
insert(iter.next());
}
public final void insert(final Collection<?> batchToSave) {
for (final Object aBatchToSave : batchToSave) {
insert(aBatchToSave);
}
}
public void save(final Object objectToSave) {
ensureNotIterable(objectToSave);
ensureNotIterable(objectToSave);
final CouchbaseDocument converted = new CouchbaseDocument();
couchbaseConverter.write(objectToSave, converted);
@@ -117,16 +121,15 @@ public class CouchbaseTemplate implements CouchbaseOperations {
}
});
}
public void save(final Collection<? extends Object> batchToSave) {
Iterator<? extends Object> iter = batchToSave.iterator();
while (iter.hasNext()) {
save(iter.next());
public void save(final Collection<?> batchToSave) {
for (final Object aBatchToSave : batchToSave) {
save(aBatchToSave);
}
}
public void update(final Object objectToSave) {
ensureNotIterable(objectToSave);
ensureNotIterable(objectToSave);
final CouchbaseDocument converted = new CouchbaseDocument();
couchbaseConverter.write(objectToSave, converted);
@@ -139,14 +142,13 @@ public class CouchbaseTemplate implements CouchbaseOperations {
});
}
public void update(final Collection<? extends Object> batchToSave) {
Iterator<? extends Object> iter = batchToSave.iterator();
while (iter.hasNext()) {
save(iter.next());
}
public void update(final Collection<?> batchToSave) {
for (final Object aBatchToSave : batchToSave) {
save(aBatchToSave);
}
}
public final <T> T findById(final String id, final Class<T> entityClass) {
String result = execute(new BucketCallback<String>() {
@Override
@@ -155,18 +157,17 @@ public class CouchbaseTemplate implements CouchbaseOperations {
}
});
if (result == null) {
return null;
}
if (result == null) {
return null;
}
CouchbaseDocument converted = new CouchbaseDocument(id);
return couchbaseConverter.read(entityClass, (CouchbaseDocument) translateDecode(result, converted));
final CouchbaseDocument converted = new CouchbaseDocument(id);
return couchbaseConverter.read(entityClass, (CouchbaseDocument) translateDecode(result, converted));
}
@Override
public <T> List<T> findByView(final String designName, final String viewName,
final Query query, final Class<T> entityClass) {
public <T> List<T> findByView(final String designName, final String viewName, final Query query, final Class<T> entityClass) {
if (!query.willIncludeDocs()) {
query.setIncludeDocs(true);
@@ -175,25 +176,23 @@ public class CouchbaseTemplate implements CouchbaseOperations {
query.setReduce(false);
}
ViewResponse response = queryView(designName, viewName, query);
final ViewResponse response = queryView(designName, viewName, query);
List<T> result = new ArrayList<T>(response.size());
for (ViewRow row : response) {
CouchbaseDocument converted = new CouchbaseDocument(row.getId());
result.add(couchbaseConverter.read(entityClass,
(CouchbaseDocument) translateDecode((String) row.getDocument(), converted)));
final List<T> result = new ArrayList<T>(response.size());
for (final ViewRow row : response) {
final CouchbaseDocument converted = new CouchbaseDocument(row.getId());
result.add(couchbaseConverter.read(entityClass, (CouchbaseDocument) translateDecode((String) row.getDocument(), converted)));
}
return result;
}
@Override
public ViewResponse queryView(final String designName, final String viewName,
final Query query) {
public ViewResponse queryView(final String designName, final String viewName, final Query query) {
return execute(new BucketCallback<ViewResponse>() {
@Override
public ViewResponse doInBucket() {
View view = client.getView(designName, viewName);
final View view = client.getView(designName, viewName);
return client.query(view, query);
}
});
@@ -223,10 +222,9 @@ public class CouchbaseTemplate implements CouchbaseOperations {
});
}
public void remove(final Collection<? extends Object> batchToRemove) {
Iterator<? extends Object> iter = batchToRemove.iterator();
while (iter.hasNext()) {
remove(iter.next());
public void remove(final Collection<?> batchToRemove) {
for (final Object aBatchToRemove : batchToRemove) {
remove(aBatchToRemove);
}
}
@@ -235,7 +233,7 @@ public class CouchbaseTemplate implements CouchbaseOperations {
try {
return action.doInBucket();
} catch (RuntimeException e) {
throw potentiallyConvertRuntimeException(e);
throw exceptionTranslator.translateExceptionIfPossible(e);
} catch (TimeoutException e) {
throw new QueryTimeoutException(e.getMessage(), e);
} catch (InterruptedException e) {
@@ -247,13 +245,13 @@ public class CouchbaseTemplate implements CouchbaseOperations {
@Override
public boolean exists(final String id) {
String result = execute(new BucketCallback<String>() {
final String result = execute(new BucketCallback<String>() {
@Override
public String doInBucket() {
return (String) client.get(id);
}
});
return result == null ? false : true;
return result != null;
}
/**
@@ -261,18 +259,13 @@ public class CouchbaseTemplate implements CouchbaseOperations {
*
* @param o the object to verify.
*/
protected final void ensureNotIterable(Object o) {
if (null != o) {
if (o.getClass().isArray() || ITERABLE_CLASSES.contains(o.getClass().getName())) {
throw new IllegalArgumentException("Cannot use a collection here.");
}
}
}
private RuntimeException potentiallyConvertRuntimeException(final RuntimeException ex) {
RuntimeException resolved = exceptionTranslator.translateExceptionIfPossible(ex);
return resolved == null ? ex : resolved;
}
protected final void ensureNotIterable(Object o) {
if (null != o) {
if (o.getClass().isArray() || ITERABLE_CLASSES.contains(o.getClass().getName())) {
throw new IllegalArgumentException("Cannot use a collection here.");
}
}
}
@Override
public CouchbaseConverter getConverter() {