Browse Source

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.
pull/1/head
Christoph Leiter 14 years ago committed by Oliver Gierke
parent
commit
2d12ba38f8
  1. 2
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
  2. 22
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AbstractMongoEventListener.java
  3. 34
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AfterLoadEvent.java
  4. 89
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AbstractMongoEventListenerUnitTest.java
  5. 4
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/SimpleMappingEventListener.java

2
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

@ -1486,7 +1486,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { @@ -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) {

22
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AbstractMongoEventListener.java

@ -43,29 +43,35 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen @@ -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);
}
}

34
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AfterLoadEvent.java

@ -16,16 +16,42 @@ @@ -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;
/**
* 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) {
public AfterLoadEvent(DBObject dbo) {
super(dbo, null);
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;
}
}

89
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AbstractMongoEventListenerUnitTest.java

@ -17,8 +17,11 @@ package org.springframework.data.mongodb.core.mapping.event; @@ -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 { @@ -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));
}
@ -46,7 +49,7 @@ public class AbstractMongoEventListenerUnitTest { @@ -46,7 +49,7 @@ 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")));
@ -63,13 +66,57 @@ public class AbstractMongoEventListenerUnitTest { @@ -63,13 +66,57 @@ 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));
}
/**
* @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 SampleEventListener extends AbstractMongoEventListener<Person> {
class SamplePersonEventListener extends AbstractMongoEventListener<Person> {
boolean invokedOnBeforeConvert;
boolean invokedOnAfterLoad;
@ -84,4 +131,36 @@ public class AbstractMongoEventListenerUnitTest { @@ -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;
}
}
}

4
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/SimpleMappingEventListener.java

@ -25,7 +25,7 @@ public class SimpleMappingEventListener extends AbstractMongoEventListener<Objec @@ -25,7 +25,7 @@ public class SimpleMappingEventListener extends AbstractMongoEventListener<Objec
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 @@ -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

Loading…
Cancel
Save