DATACOUCH-71 - Add support for JSR 303 validation.
This changeset adds validation support for entities, and since this depends on events, the event functionality has been added as well. Now also generic event listeners can be attached.
This commit is contained in:
@@ -28,6 +28,8 @@ import net.spy.memcached.ReplicateTo;
|
||||
import net.spy.memcached.internal.OperationFuture;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.dao.QueryTimeoutException;
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
@@ -39,6 +41,12 @@ 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.couchbase.core.mapping.event.AfterDeleteEvent;
|
||||
import org.springframework.data.couchbase.core.mapping.event.AfterSaveEvent;
|
||||
import org.springframework.data.couchbase.core.mapping.event.BeforeConvertEvent;
|
||||
import org.springframework.data.couchbase.core.mapping.event.BeforeDeleteEvent;
|
||||
import org.springframework.data.couchbase.core.mapping.event.BeforeSaveEvent;
|
||||
import org.springframework.data.couchbase.core.mapping.event.CouchbaseMappingEvent;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
@@ -56,7 +64,7 @@ import java.util.concurrent.TimeoutException;
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventPublisherAware {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CouchbaseTemplate.class);
|
||||
private static final Collection<String> ITERABLE_CLASSES;
|
||||
@@ -66,6 +74,7 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
protected final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext;
|
||||
private final CouchbaseExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator();
|
||||
private final TranslationService translationService;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
private CouchbaseConverter couchbaseConverter;
|
||||
private WriteResultChecking writeResultChecking = DEFAULT_WRITE_RESULT_CHECKING;
|
||||
@@ -86,6 +95,10 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
this(client, null, null);
|
||||
}
|
||||
|
||||
public CouchbaseTemplate(final CouchbaseClient client, final TranslationService translationService) {
|
||||
this(client, null, translationService);
|
||||
}
|
||||
|
||||
public CouchbaseTemplate(final CouchbaseClient client, final CouchbaseConverter couchbaseConverter, final TranslationService translationService) {
|
||||
this.client = client;
|
||||
this.couchbaseConverter = couchbaseConverter == null ? getDefaultConverter() : couchbaseConverter;
|
||||
@@ -93,11 +106,9 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
mappingContext = this.couchbaseConverter.getMappingContext();
|
||||
}
|
||||
|
||||
public CouchbaseTemplate(final CouchbaseClient client, final TranslationService translationService) {
|
||||
this.client = client;
|
||||
couchbaseConverter = couchbaseConverter == null ? getDefaultConverter() : couchbaseConverter;
|
||||
this.translationService = translationService == null ? getDefaultTranslationService() : translationService;
|
||||
mappingContext = couchbaseConverter.getMappingContext();
|
||||
@Override
|
||||
public void setApplicationEventPublisher(final ApplicationEventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
private static CouchbaseConverter getDefaultConverter() {
|
||||
@@ -282,9 +293,11 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty();
|
||||
final Long version = versionProperty != null ? beanWrapper.getProperty(versionProperty, Long.class, true) : null;
|
||||
|
||||
maybeEmitEvent(new BeforeConvertEvent<Object>(objectToSave));
|
||||
final CouchbaseDocument converted = new CouchbaseDocument();
|
||||
couchbaseConverter.write(objectToSave, converted);
|
||||
|
||||
maybeEmitEvent(new BeforeSaveEvent<Object>(objectToSave, converted));
|
||||
execute(new BucketCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInBucket() throws InterruptedException, ExecutionException {
|
||||
@@ -310,6 +323,7 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
}
|
||||
}
|
||||
});
|
||||
maybeEmitEvent(new AfterSaveEvent<Object>(objectToSave, converted));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -334,9 +348,11 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
}
|
||||
}
|
||||
|
||||
maybeEmitEvent(new BeforeConvertEvent<Object>(objectToInsert));
|
||||
final CouchbaseDocument converted = new CouchbaseDocument();
|
||||
couchbaseConverter.write(objectToInsert, converted);
|
||||
|
||||
maybeEmitEvent(new BeforeSaveEvent<Object>(objectToInsert, converted));
|
||||
execute(new BucketCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInBucket() throws InterruptedException, ExecutionException {
|
||||
@@ -354,6 +370,7 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
maybeEmitEvent(new AfterSaveEvent<Object>(objectToInsert, converted));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -373,9 +390,11 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty();
|
||||
final Long version = versionProperty != null ? beanWrapper.getProperty(versionProperty, Long.class, true) : null;
|
||||
|
||||
maybeEmitEvent(new BeforeConvertEvent<Object>(objectToUpdate));
|
||||
final CouchbaseDocument converted = new CouchbaseDocument();
|
||||
couchbaseConverter.write(objectToUpdate, converted);
|
||||
|
||||
maybeEmitEvent(new BeforeSaveEvent<Object>(objectToUpdate, converted));
|
||||
execute(new BucketCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInBucket() throws InterruptedException, ExecutionException {
|
||||
@@ -397,6 +416,7 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
}
|
||||
}
|
||||
});
|
||||
maybeEmitEvent(new AfterSaveEvent<Object>(objectToUpdate, converted));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -410,6 +430,7 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
public void remove(final Object objectToRemove, final PersistTo persistTo, final ReplicateTo replicateTo) {
|
||||
ensureNotIterable(objectToRemove);
|
||||
|
||||
maybeEmitEvent(new BeforeDeleteEvent<Object>(objectToRemove));
|
||||
if (objectToRemove instanceof String) {
|
||||
execute(new BucketCallback<Boolean>() {
|
||||
@Override
|
||||
@@ -417,6 +438,7 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
return client.delete((String) objectToRemove, persistTo, replicateTo).get();
|
||||
}
|
||||
});
|
||||
maybeEmitEvent(new AfterDeleteEvent<Object>(objectToRemove));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -429,6 +451,7 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
return client.delete(converted.getId());
|
||||
}
|
||||
});
|
||||
maybeEmitEvent(new AfterDeleteEvent<Object>(objectToRemove));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -455,4 +478,16 @@ public class CouchbaseTemplate implements CouchbaseOperations {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to publish an event if the event publisher is set.
|
||||
*
|
||||
* @param event the event to emit.
|
||||
* @param <T> the enclosed type.
|
||||
*/
|
||||
protected <T> void maybeEmitEvent(final CouchbaseMappingEvent<T> event) {
|
||||
if (eventPublisher != null) {
|
||||
eventPublisher.publishEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2013 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.data.couchbase.core.mapping.event;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
|
||||
/**
|
||||
* Base class to implement domain class specific {@link ApplicationListener}s.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Martin Baumgartner
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class AbstractCouchbaseEventListener<E> implements ApplicationListener<CouchbaseMappingEvent<?>> {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractCouchbaseEventListener.class);
|
||||
private final Class<?> domainClass;
|
||||
|
||||
public AbstractCouchbaseEventListener() {
|
||||
Class<?> typeArgument = GenericTypeResolver.resolveTypeArgument(getClass(), AbstractCouchbaseEventListener.class);
|
||||
domainClass = typeArgument == null ? Object.class : typeArgument;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void onApplicationEvent(CouchbaseMappingEvent<?> event) {
|
||||
if (event instanceof BeforeDeleteEvent) {
|
||||
onBeforeDelete(event.getDocument());
|
||||
return;
|
||||
} else if (event instanceof AfterDeleteEvent) {
|
||||
onAfterDelete(event.getDocument());
|
||||
return;
|
||||
}
|
||||
|
||||
E source = (E) event.getSource();
|
||||
// Check for matching domain type and invoke callbacks
|
||||
if (source != null && !domainClass.isAssignableFrom(source.getClass())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event instanceof BeforeConvertEvent) {
|
||||
onBeforeConvert(source);
|
||||
} else if (event instanceof BeforeSaveEvent) {
|
||||
onBeforeSave(source, event.getDocument());
|
||||
} else if (event instanceof AfterSaveEvent) {
|
||||
onAfterSave(source, event.getDocument());
|
||||
}
|
||||
}
|
||||
|
||||
public void onBeforeConvert(E source) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onBeforeConvert({})", source);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBeforeSave(E source, CouchbaseDocument doc) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onBeforeSave({}, {})", source, doc);
|
||||
}
|
||||
}
|
||||
|
||||
public void onAfterSave(E source, CouchbaseDocument doc) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterSave({}, {})", source, doc);
|
||||
}
|
||||
}
|
||||
|
||||
public void onAfterDelete(CouchbaseDocument doc) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterConvert({})", doc);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBeforeDelete(CouchbaseDocument doc) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterConvert({})", doc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013 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.data.couchbase.core.mapping.event;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class AfterDeleteEvent<E> extends CouchbaseMappingEvent<E> {
|
||||
|
||||
public AfterDeleteEvent(E source) {
|
||||
super(source, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2013 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.data.couchbase.core.mapping.event;
|
||||
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class AfterSaveEvent<E> extends CouchbaseMappingEvent<E> {
|
||||
|
||||
public AfterSaveEvent(E source, CouchbaseDocument document) {
|
||||
super(source, document);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013 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.data.couchbase.core.mapping.event;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class BeforeConvertEvent<E> extends CouchbaseMappingEvent<E> {
|
||||
|
||||
public BeforeConvertEvent(E source) {
|
||||
super(source, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013 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.data.couchbase.core.mapping.event;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class BeforeDeleteEvent<E> extends CouchbaseMappingEvent<E> {
|
||||
|
||||
public BeforeDeleteEvent(E source) {
|
||||
super(source, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2013 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.data.couchbase.core.mapping.event;
|
||||
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class BeforeSaveEvent<E> extends CouchbaseMappingEvent<E> {
|
||||
|
||||
public BeforeSaveEvent(E source, CouchbaseDocument document) {
|
||||
super(source, document);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2013 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.data.couchbase.core.mapping.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
|
||||
/**
|
||||
* A mapping event.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseMappingEvent<T> extends ApplicationEvent {
|
||||
|
||||
private final CouchbaseDocument document;
|
||||
|
||||
public CouchbaseMappingEvent(T source, CouchbaseDocument document) {
|
||||
super(source);
|
||||
this.document = document;
|
||||
}
|
||||
|
||||
public CouchbaseDocument getDocument() {
|
||||
return document;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T getSource() {
|
||||
return (T) super.getSource();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2013 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.data.couchbase.core.mapping.event;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
|
||||
/**
|
||||
* A{@link ApplicationListener} for Couchbase mapping events logging the events.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class LoggingEventListener extends AbstractCouchbaseEventListener<Object> {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingEventListener.class);
|
||||
|
||||
@Override
|
||||
public void onBeforeDelete(CouchbaseDocument doc) {
|
||||
LOGGER.info("onBeforeDelete: {}", doc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterDelete(CouchbaseDocument doc) {
|
||||
LOGGER.info("onAfterDelete: {}", doc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterSave(Object source, CouchbaseDocument doc) {
|
||||
LOGGER.info("onAfterSave: {}, {}", source, doc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeSave(Object source, CouchbaseDocument doc) {
|
||||
LOGGER.info("onBeforeSave: {}, {}", source, doc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeConvert(Object source) {
|
||||
LOGGER.info("onBeforeConvert: {}, {}", source);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2013 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.data.couchbase.core.mapping.event;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import javax.validation.Validator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* javax.validation dependant entities validator. When it is registered as Spring component its automatically invoked
|
||||
* before entities are saved in database.
|
||||
*
|
||||
* @author Maciej Walkowiak
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class ValidatingCouchbaseEventListener extends AbstractCouchbaseEventListener<Object> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ValidatingCouchbaseEventListener.class);
|
||||
|
||||
private final Validator validator;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ValidatingCouchbaseEventListener} using the given {@link Validator}.
|
||||
*
|
||||
* @param validator must not be {@literal null}.
|
||||
*/
|
||||
public ValidatingCouchbaseEventListener(Validator validator) {
|
||||
Assert.notNull(validator);
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void onBeforeSave(Object source, CouchbaseDocument dbo) {
|
||||
|
||||
LOG.debug("Validating object: {}", source);
|
||||
Set violations = validator.validate(source);
|
||||
|
||||
if (!violations.isEmpty()) {
|
||||
|
||||
LOG.info("During object: {} validation violations found: {}", source, violations);
|
||||
throw new ConstraintViolationException(violations);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user