DATADOC-289 - Filter AfterLoadEvent for specific domain type.
AfterLoadEvent can now be typed to a domain type again and will only be invoked if documents are loaded that shall be mapped onto the declared type.
This commit is contained in:
committed by
Oliver Gierke
parent
1554d489ca
commit
2d12ba38f8
@@ -1486,7 +1486,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
public T doWith(DBObject object) {
|
||||
if (null != object) {
|
||||
maybeEmitEvent(new AfterLoadEvent(object));
|
||||
maybeEmitEvent(new AfterLoadEvent<T>(object, type));
|
||||
}
|
||||
T source = reader.read(type, object);
|
||||
if (null != source) {
|
||||
|
||||
@@ -43,29 +43,35 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onApplicationEvent(MongoMappingEvent<?> event) {
|
||||
|
||||
Object source = event.getSource();
|
||||
|
||||
|
||||
// Invoke domain type independent events
|
||||
if (event instanceof AfterLoadEvent) {
|
||||
onAfterLoad(((AfterLoadEvent) event).getSource());
|
||||
AfterLoadEvent<?> afterLoadEvent = (AfterLoadEvent<?>) event;
|
||||
|
||||
if (domainClass.isAssignableFrom(afterLoadEvent.getType())) {
|
||||
onAfterLoad(event.getDBObject());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
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((E) source);
|
||||
onBeforeConvert(source);
|
||||
} else if (event instanceof BeforeSaveEvent) {
|
||||
onBeforeSave((E) source, event.getDBObject());
|
||||
onBeforeSave(source, event.getDBObject());
|
||||
} else if (event instanceof AfterSaveEvent) {
|
||||
onAfterSave((E) source, event.getDBObject());
|
||||
onAfterSave(source, event.getDBObject());
|
||||
} else if (event instanceof AfterConvertEvent) {
|
||||
onAfterConvert(event.getDBObject(), (E) source);
|
||||
onAfterConvert(event.getDBObject(), source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,16 +16,42 @@
|
||||
|
||||
package org.springframework.data.mongodb.core.mapping.event;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* Event to be triggered after loading {@link DBObject}s to be mapped onto a given type.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Jon Brisbin
|
||||
* @author Christoph Leiter
|
||||
*/
|
||||
public class AfterLoadEvent extends MongoMappingEvent<DBObject> {
|
||||
public class AfterLoadEvent<T> extends MongoMappingEvent<DBObject> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Class<T> type;
|
||||
|
||||
public AfterLoadEvent(DBObject dbo) {
|
||||
super(dbo, null);
|
||||
/**
|
||||
* Creates a new {@link AfterLoadEvent} for the given {@link DBObject} and type.
|
||||
*
|
||||
* @param dbo must not be {@literal null}.
|
||||
* @param type must not be {@literal null}.
|
||||
*/
|
||||
public AfterLoadEvent(DBObject dbo, Class<T> type) {
|
||||
|
||||
super(dbo, dbo);
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type for which the {@link AfterLoadEvent} shall be invoked for.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,11 @@ package org.springframework.data.mongodb.core.mapping.event;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.data.mongodb.core.mapping.Account;
|
||||
import org.springframework.data.mongodb.repository.Contact;
|
||||
import org.springframework.data.mongodb.repository.Person;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
@@ -35,7 +38,7 @@ public class AbstractMongoEventListenerUnitTest {
|
||||
public void invokesCallbackForEventForPerson() {
|
||||
|
||||
MongoMappingEvent<Person> event = new BeforeConvertEvent<Person>(new Person("Dave", "Matthews"));
|
||||
SampleEventListener listener = new SampleEventListener();
|
||||
SamplePersonEventListener listener = new SamplePersonEventListener();
|
||||
listener.onApplicationEvent(event);
|
||||
assertThat(listener.invokedOnBeforeConvert, is(true));
|
||||
}
|
||||
@@ -45,8 +48,8 @@ public class AbstractMongoEventListenerUnitTest {
|
||||
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
|
||||
context.refresh();
|
||||
|
||||
SampleEventListener listener = new SampleEventListener();
|
||||
|
||||
SamplePersonEventListener listener = new SamplePersonEventListener();
|
||||
context.addApplicationListener(listener);
|
||||
|
||||
context.publishEvent(new BeforeConvertEvent<Person>(new Person("Dave", "Matthews")));
|
||||
@@ -62,15 +65,59 @@ public class AbstractMongoEventListenerUnitTest {
|
||||
*/
|
||||
@Test
|
||||
public void afterLoadEffectGetsHandledCorrectly() {
|
||||
|
||||
SampleEventListener listener = new SampleEventListener();
|
||||
listener.onApplicationEvent(new AfterLoadEvent(new BasicDBObject()));
|
||||
|
||||
SamplePersonEventListener listener = new SamplePersonEventListener();
|
||||
listener.onApplicationEvent(new AfterLoadEvent<Person>(new BasicDBObject(), Person.class));
|
||||
assertThat(listener.invokedOnAfterLoad, is(true));
|
||||
}
|
||||
|
||||
|
||||
class SampleEventListener extends AbstractMongoEventListener<Person> {
|
||||
|
||||
/**
|
||||
* @see DATADOC-289
|
||||
*/
|
||||
@Test
|
||||
public void afterLoadEventGetsFilteredForDomainType() {
|
||||
|
||||
SamplePersonEventListener personListener = new SamplePersonEventListener();
|
||||
SampleAccountEventListener accountListener = new SampleAccountEventListener();
|
||||
personListener.onApplicationEvent(new AfterLoadEvent<Person>(new BasicDBObject(), Person.class));
|
||||
accountListener.onApplicationEvent(new AfterLoadEvent<Person>(new BasicDBObject(), Person.class));
|
||||
|
||||
assertThat(personListener.invokedOnAfterLoad, is(true));
|
||||
assertThat(accountListener.invokedOnAfterLoad, is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATADOC-289
|
||||
*/
|
||||
@Test
|
||||
public void afterLoadEventGetsFilteredForDomainTypeWorksForSubtypes() {
|
||||
|
||||
SamplePersonEventListener personListener = new SamplePersonEventListener();
|
||||
SampleContactEventListener contactListener = new SampleContactEventListener();
|
||||
personListener.onApplicationEvent(new AfterLoadEvent<Person>(new BasicDBObject(), Person.class));
|
||||
contactListener.onApplicationEvent(new AfterLoadEvent<Person>(new BasicDBObject(), Person.class));
|
||||
|
||||
assertThat(personListener.invokedOnAfterLoad, is(true));
|
||||
assertThat(contactListener.invokedOnAfterLoad, is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATADOC-289
|
||||
*/
|
||||
@Test
|
||||
public void afterLoadEventGetsFilteredForDomainTypeWorksForSubtypes2() {
|
||||
|
||||
SamplePersonEventListener personListener = new SamplePersonEventListener();
|
||||
SampleContactEventListener contactListener = new SampleContactEventListener();
|
||||
personListener.onApplicationEvent(new AfterLoadEvent<Contact>(new BasicDBObject(), Contact.class));
|
||||
contactListener.onApplicationEvent(new AfterLoadEvent<Contact>(new BasicDBObject(), Contact.class));
|
||||
|
||||
assertThat(personListener.invokedOnAfterLoad, is(false));
|
||||
assertThat(contactListener.invokedOnAfterLoad, is(true));
|
||||
}
|
||||
|
||||
class SamplePersonEventListener extends AbstractMongoEventListener<Person> {
|
||||
|
||||
boolean invokedOnBeforeConvert;
|
||||
boolean invokedOnAfterLoad;
|
||||
|
||||
@@ -84,4 +131,36 @@ public class AbstractMongoEventListenerUnitTest {
|
||||
invokedOnAfterLoad = true;
|
||||
}
|
||||
}
|
||||
|
||||
class SampleContactEventListener extends AbstractMongoEventListener<Contact> {
|
||||
|
||||
boolean invokedOnBeforeConvert;
|
||||
boolean invokedOnAfterLoad;
|
||||
|
||||
@Override
|
||||
public void onBeforeConvert(Contact source) {
|
||||
invokedOnBeforeConvert = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
invokedOnAfterLoad = true;
|
||||
}
|
||||
}
|
||||
|
||||
class SampleAccountEventListener extends AbstractMongoEventListener<Account> {
|
||||
|
||||
boolean invokedOnBeforeConvert;
|
||||
boolean invokedOnAfterLoad;
|
||||
|
||||
@Override
|
||||
public void onBeforeConvert(Account source) {
|
||||
invokedOnBeforeConvert = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
invokedOnAfterLoad = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ import java.util.ArrayList;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
|
||||
public class SimpleMappingEventListener extends AbstractMongoEventListener<Object> {
|
||||
public class SimpleMappingEventListener extends AbstractMongoEventListener<Object> {
|
||||
|
||||
public final ArrayList<BeforeConvertEvent<Object>> onBeforeConvertEvents = new ArrayList<BeforeConvertEvent<Object>>();
|
||||
public final ArrayList<BeforeSaveEvent<Object>> onBeforeSaveEvents = new ArrayList<BeforeSaveEvent<Object>>();
|
||||
public final ArrayList<AfterSaveEvent<Object>> onAfterSaveEvents = new ArrayList<AfterSaveEvent<Object>>();
|
||||
public final ArrayList<AfterLoadEvent> onAfterLoadEvents = new ArrayList<AfterLoadEvent>();
|
||||
public final ArrayList<AfterLoadEvent<Object>> onAfterLoadEvents = new ArrayList<AfterLoadEvent<Object>>();
|
||||
public final ArrayList<AfterConvertEvent<Object>> onAfterConvertEvents = new ArrayList<AfterConvertEvent<Object>>();
|
||||
|
||||
@Override
|
||||
@@ -45,7 +45,7 @@ public class SimpleMappingEventListener extends AbstractMongoEventListener<Objec
|
||||
|
||||
@Override
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
onAfterLoadEvents.add(new AfterLoadEvent(dbo));
|
||||
onAfterLoadEvents.add(new AfterLoadEvent<Object>(dbo, Object.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user