DATAREST-388 - Improved annotation based event handling.

The annotation based event handling now relies on the type of the first method argument to determine the domain type the handler is interested in. Improved method invocation to not unnecessarily wrap exceptions thrown from them. Changed the test cases to throw a dedicated runtime exception to implicitly test that the 

Renamed LinkSaveEvent to LinkedEntityEvent as it's not only used for save-events for entities. Make use of Methods' USER_METHOD filter. Moved the class into the util package. Removed the UUID converter as Spring's DefaultFormattingConversionService provides it out of the box.

Added missing license headers and JavaDoc. Deprecated Class<?> attributes on handling annotations.

Related pull request: #151.
This commit is contained in:
Oliver Gierke
2014-12-04 18:56:29 +01:00
parent e6a19a366d
commit 7f990b006b
27 changed files with 675 additions and 351 deletions

View File

@@ -1,3 +1,18 @@
/*
* Copyright 2014 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.rest.core.context;
import org.junit.Before;
@@ -10,6 +25,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.rest.core.RepositoryTestsConfig;
import org.springframework.data.rest.core.domain.jpa.AnnotatedPersonEventHandler;
import org.springframework.data.rest.core.domain.jpa.EventHandlerInvokedException;
import org.springframework.data.rest.core.domain.jpa.Person;
import org.springframework.data.rest.core.domain.jpa.PersonBeforeSaveHandler;
import org.springframework.data.rest.core.domain.jpa.PersonRepository;
@@ -18,7 +34,7 @@ import org.springframework.data.rest.core.event.AfterDeleteEvent;
import org.springframework.data.rest.core.event.AfterLinkDeleteEvent;
import org.springframework.data.rest.core.event.AfterLinkSaveEvent;
import org.springframework.data.rest.core.event.AfterSaveEvent;
import org.springframework.data.rest.core.event.AnnotatedHandlerBeanPostProcessor;
import org.springframework.data.rest.core.event.AnnotatedEventHandlerInvoker;
import org.springframework.data.rest.core.event.BeforeCreateEvent;
import org.springframework.data.rest.core.event.BeforeDeleteEvent;
import org.springframework.data.rest.core.event.BeforeLinkDeleteEvent;
@@ -32,6 +48,7 @@ import org.springframework.transaction.annotation.Transactional;
* Tests around the {@link org.springframework.context.ApplicationEvent} handling abstractions.
*
* @author Jon Brisbin
* @author Oliver Gierke
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@@ -53,8 +70,8 @@ public class RepositoryEventIntegrationTests {
}
@Bean
public AnnotatedHandlerBeanPostProcessor annotatedHandlerBeanPostProcessor() {
return new AnnotatedHandlerBeanPostProcessor();
public static AnnotatedEventHandlerInvoker annotatedEventHandlerInvoker() {
return new AnnotatedEventHandlerInvoker();
}
}
@@ -67,54 +84,83 @@ public class RepositoryEventIntegrationTests {
person = people.save(new Person("Jane", "Doe"));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchBeforeCreate() throws Exception {
appCtx.publishEvent(new BeforeCreateEvent(person));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchAfterCreate() throws Exception {
appCtx.publishEvent(new AfterCreateEvent(person));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchBeforeSave() throws Exception {
appCtx.publishEvent(new BeforeSaveEvent(person));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchAfterSave() throws Exception {
appCtx.publishEvent(new AfterSaveEvent(person));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchBeforeDelete() throws Exception {
appCtx.publishEvent(new BeforeDeleteEvent(person));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchAfterDelete() throws Exception {
appCtx.publishEvent(new AfterDeleteEvent(person));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchBeforeLinkSave() throws Exception {
appCtx.publishEvent(new BeforeLinkSaveEvent(person, new Object()));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchAfterLinkSave() throws Exception {
appCtx.publishEvent(new AfterLinkSaveEvent(person, new Object()));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchBeforeLinkDelete() throws Exception {
appCtx.publishEvent(new BeforeLinkDeleteEvent(person, new Object()));
}
@Test(expected = RuntimeException.class)
/**
* @see DATAREST-388
*/
@Test(expected = EventHandlerInvokedException.class)
public void shouldDispatchAfterLinkDelete() throws Exception {
appCtx.publishEvent(new AfterLinkDeleteEvent(person, new Object()));
}
}

View File

@@ -1,3 +1,18 @@
/*
* Copyright 2012-2014 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.rest.core.domain.jpa;
import org.springframework.data.rest.core.annotation.HandleAfterCreate;
@@ -13,33 +28,37 @@ import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
/**
* Sample annotation-based event handler.
*
* @author Jon Brisbin
* @author Oliver Gierke
*/
@RepositoryEventHandler(Person.class)
@RepositoryEventHandler
public class AnnotatedPersonEventHandler {
@HandleAfterCreate
@HandleAfterDelete
@HandleAfterSave
public void handleAfter(Person p) {
throw new RuntimeException();
throw new EventHandlerInvokedException();
}
@HandleAfterLinkDelete
@HandleAfterLinkSave
public void handleAfterLink(Person p, Object o) {
throw new RuntimeException();
throw new EventHandlerInvokedException();
}
@HandleBeforeCreate
@HandleBeforeDelete
@HandleBeforeSave
public void handleBefore(Person p) {
throw new RuntimeException();
throw new EventHandlerInvokedException();
}
@HandleBeforeLinkDelete
@HandleBeforeLinkSave
public void handleBeforeLink(Person p, Object o) {
throw new RuntimeException();
throw new EventHandlerInvokedException();
}
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2014 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.rest.core.domain.jpa;
/**
* @author Oliver Gierke
*/
public class EventHandlerInvokedException extends RuntimeException {
private static final long serialVersionUID = -7879286986960261090L;
}

View File

@@ -1,13 +1,34 @@
/*
* Copyright 2012-2014 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.rest.core.domain.jpa;
import org.springframework.data.rest.core.event.AbstractRepositoryEventListener;
/**
* @author Jon Brisbin
* @author Oliver Gierke
*/
public class PersonBeforeSaveHandler extends AbstractRepositoryEventListener<Person> {
/*
* (non-Javadoc)
* @see org.springframework.data.rest.core.event.AbstractRepositoryEventListener#onBeforeSave(java.lang.Object)
*/
@Override
protected void onBeforeSave(Person person) {
throw new RuntimeException();
throw new EventHandlerInvokedException();
}
}