From 9208a49b8c7766d74a2398eaef9d1adaf1bcf8a7 Mon Sep 17 00:00:00 2001 From: Nicki Watt Date: Mon, 2 Sep 2013 14:41:30 +0100 Subject: [PATCH] DATAGRAPH-365 : before and after delete events --- .../neo4j/lifecycle/AfterDeleteEvent.java | 22 ++++ .../neo4j/lifecycle/BeforeDeleteEvent.java | 22 ++++ .../data/neo4j/lifecycle/DeleteEvent.java | 8 +- .../data/neo4j/support/Neo4jTemplate.java | 9 +- .../lifecycle/AfterDeleteEventTests.java | 107 +++++++++++++++ .../lifecycle/BeforeDeleteEventTests.java | 124 ++++++++++++++++++ .../neo4j/lifecycle/DeleteEventTests.java | 26 ++-- 7 files changed, 303 insertions(+), 15 deletions(-) create mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/AfterDeleteEvent.java create mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/BeforeDeleteEvent.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/AfterDeleteEventTests.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/BeforeDeleteEventTests.java diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/AfterDeleteEvent.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/AfterDeleteEvent.java new file mode 100644 index 000000000..3262e0a72 --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/AfterDeleteEvent.java @@ -0,0 +1,22 @@ +/** + * Copyright 2011 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.neo4j.lifecycle; + +public class AfterDeleteEvent extends DeleteEvent { + public AfterDeleteEvent(Object source, T entity) { + super(source, entity); + } +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/BeforeDeleteEvent.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/BeforeDeleteEvent.java new file mode 100644 index 000000000..ac06eebe8 --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/BeforeDeleteEvent.java @@ -0,0 +1,22 @@ +/** + * Copyright 2011 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.neo4j.lifecycle; + +public class BeforeDeleteEvent extends Neo4jLifecycleEvent { + public BeforeDeleteEvent(Object source, T entity) { + super(source, entity); + } +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/DeleteEvent.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/DeleteEvent.java index b42087911..428a50884 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/DeleteEvent.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/lifecycle/DeleteEvent.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -15,8 +15,14 @@ */ package org.springframework.data.neo4j.lifecycle; +/** + * @deprecated Rather use the AfterDeleteEvent + * @param + */ +@Deprecated public class DeleteEvent extends Neo4jLifecycleEvent { public DeleteEvent(Object source, T entity) { super(source, entity); } } + diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java index ebd1d6cad..c9d4a167e 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java @@ -39,9 +39,10 @@ import org.springframework.data.neo4j.core.GraphDatabase; import org.springframework.data.neo4j.core.TypeRepresentationStrategy; import org.springframework.data.neo4j.core.UncategorizedGraphStoreException; import org.springframework.data.neo4j.fieldaccess.GraphBackedEntityIterableWrapper; +import org.springframework.data.neo4j.lifecycle.AfterDeleteEvent; import org.springframework.data.neo4j.lifecycle.AfterSaveEvent; +import org.springframework.data.neo4j.lifecycle.BeforeDeleteEvent; import org.springframework.data.neo4j.lifecycle.BeforeSaveEvent; -import org.springframework.data.neo4j.lifecycle.DeleteEvent; import org.springframework.data.neo4j.mapping.IndexInfo; import org.springframework.data.neo4j.mapping.MappingPolicy; import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty; @@ -219,9 +220,9 @@ public class Neo4jTemplate implements Neo4jOperations, ApplicationContextAware { @Override public void delete(final Object entity) { - infrastructure.getEntityRemover().remove(entity); - - if (applicationContext != null) applicationContext.publishEvent(new DeleteEvent(this, entity)); + if (applicationContext != null) applicationContext.publishEvent(new BeforeDeleteEvent(this, entity)); + infrastructure.getEntityRemover().remove(entity); + if (applicationContext != null) applicationContext.publishEvent(new AfterDeleteEvent(this, entity)); } /** diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/AfterDeleteEventTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/AfterDeleteEventTests.java new file mode 100644 index 000000000..38bb9680d --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/AfterDeleteEventTests.java @@ -0,0 +1,107 @@ +/** + * Copyright 2011 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.neo4j.lifecycle; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.test.TestGraphDatabaseFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.neo4j.config.EnableNeo4jRepositories; +import org.springframework.data.neo4j.config.Neo4jConfiguration; +import org.springframework.data.neo4j.support.Neo4jTemplate; +import org.springframework.data.neo4j.support.node.Neo4jHelper; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@Transactional +public class AfterDeleteEventTests { + @Configuration + @EnableNeo4jRepositories + static class TestConfig extends Neo4jConfiguration { + @Bean + GraphDatabaseService graphDatabaseService() { + return new TestGraphDatabaseFactory().newImpermanentDatabase(); + } + + @Bean + ApplicationListener> afterDeleteEventApplicationListener() { + return new ApplicationListener>() { + + @Override + public void onApplicationEvent(AfterDeleteEvent event) { + afterProgramDeleteEvents.add(event.getEntity()); + lastEvent = Event.AFTER_DELETE; + } + }; + } + + + } + + @Autowired + Neo4jTemplate template; + + @Autowired + GraphDatabaseService graphDatabaseService; + + enum Event { NONE, BEFORE_DELETE, AFTER_DELETE } + + static Event lastEvent = Event.NONE; + static List afterProgramDeleteEvents = new ArrayList(); + + + @BeforeTransaction + public void beforeTransaction() { + Neo4jHelper.cleanDb(template); + } + + @Before + public void before() { + lastEvent = Event.NONE; + afterProgramDeleteEvents.clear(); + } + + @Test + public void shouldFireAfterEntityIsDeleted() throws Exception { + assertEquals(Event.NONE, lastEvent); + assertThat(afterProgramDeleteEvents, hasSize(0)); + + Program sark = template.save(new Program("Sark")); + template.delete(sark); + + assertThat(afterProgramDeleteEvents, hasSize(1)); + assertEquals(Event.AFTER_DELETE, lastEvent); + } + +} + diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/BeforeDeleteEventTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/BeforeDeleteEventTests.java new file mode 100644 index 000000000..ab55e7bc6 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/BeforeDeleteEventTests.java @@ -0,0 +1,124 @@ +/** + * Copyright 2011 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.neo4j.lifecycle; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.test.TestGraphDatabaseFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.neo4j.annotation.GraphId; +import org.springframework.data.neo4j.annotation.NodeEntity; +import org.springframework.data.neo4j.config.EnableNeo4jRepositories; +import org.springframework.data.neo4j.config.Neo4jConfiguration; +import org.springframework.data.neo4j.support.Neo4jTemplate; +import org.springframework.data.neo4j.support.node.Neo4jHelper; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@Transactional +public class BeforeDeleteEventTests { + @Configuration + @EnableNeo4jRepositories + static class TestConfig extends Neo4jConfiguration { + @Bean + GraphDatabaseService graphDatabaseService() { + return new TestGraphDatabaseFactory().newImpermanentDatabase(); + } + + @Bean + ApplicationListener> beforeDeleteEventApplicationListener() { + return new ApplicationListener>() { + + @Override + public void onApplicationEvent(BeforeDeleteEvent event) { + beforeProgramDeleteEvents.add(event.getEntity()); + lastEvent = Event.BEFORE_DELETE; + } + }; + } + + + } + + @Autowired + Neo4jTemplate template; + + @Autowired + GraphDatabaseService graphDatabaseService; + + enum Event { NONE, BEFORE_DELETE, AFTER_DELETE } + + static Event lastEvent = Event.NONE; + static List beforeProgramDeleteEvents = new ArrayList(); + + + @BeforeTransaction + public void beforeTransaction() { + Neo4jHelper.cleanDb(template); + } + + @Before + public void before() { + lastEvent = Event.NONE; + beforeProgramDeleteEvents.clear(); + } + + @Test + public void shouldFireBeforeEntityIsDeleted() throws Exception { + assertEquals(Event.NONE, lastEvent); + assertThat(beforeProgramDeleteEvents, hasSize(0)); + + Program sark = template.save(new Program("Sark")); + template.delete(sark); + + assertThat(beforeProgramDeleteEvents, hasSize(1)); + assertEquals(Event.BEFORE_DELETE, lastEvent); + } + +} + +@NodeEntity +class Program { + @GraphId + Long id; + + String name; + + Program() { + } + + public Program(String name) { + this.name = name; + } +} + diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/DeleteEventTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/DeleteEventTests.java index f5fa33f28..682a929f6 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/DeleteEventTests.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/lifecycle/DeleteEventTests.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -40,21 +40,27 @@ import java.util.LinkedList; import static org.junit.Assert.assertThat; import static org.hamcrest.CoreMatchers.hasItem; +@Deprecated @NodeEntity -class Program { +class DeprecatedProgram { @GraphId Long id; String name; - Program() { + DeprecatedProgram() { } - public Program(String name) { + public DeprecatedProgram(String name) { this.name = name; } } +// This test should be deprecated moving forward as it is replaced by +// BeforeAndAfterDeleteEventTests, however as we are leaving the +// DeleteEvent class for backwards compatibility, we leave this test +// here too to ensure we don't break anything. +@Deprecated @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @Transactional @@ -68,10 +74,10 @@ public class DeleteEventTests { } @Bean - ApplicationListener> deleteEventApplicationListener() { - return new ApplicationListener>() { + ApplicationListener> deleteEventApplicationListener() { + return new ApplicationListener>() { @Override - public void onApplicationEvent(DeleteEvent event) { + public void onApplicationEvent(DeleteEvent event) { deletions.add(event.getEntity()); } }; @@ -84,7 +90,7 @@ public class DeleteEventTests { @Autowired GraphDatabaseService graphDatabaseService; - static final LinkedList deletions = new LinkedList(); + static final LinkedList deletions = new LinkedList(); @BeforeTransaction public void beforeTransaction() { @@ -98,10 +104,10 @@ public class DeleteEventTests { @Test public void shouldFireEventOnNodeDeletion() throws Exception { - Program sark = template.save(new Program("Sark")); + DeprecatedProgram sark = template.save(new DeprecatedProgram("Sark")); template.delete(sark); assertThat(deletions, hasItem(sark)); } -} +} \ No newline at end of file