You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/03/16 07:25:29 UTC

cayenne git commit: CAY-2267 Contribute lifecycle events listeners via DI

Repository: cayenne
Updated Branches:
  refs/heads/master f8bb12770 -> e68d4640f


CAY-2267 Contribute lifecycle events listeners via DI


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/e68d4640
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/e68d4640
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/e68d4640

Branch: refs/heads/master
Commit: e68d4640f2d500f70818ce195633fa8f98b79a2c
Parents: f8bb127
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Mar 16 10:14:27 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Mar 16 10:14:27 2017 +0300

----------------------------------------------------------------------
 .../apache/cayenne/configuration/Constants.java |  7 +++++
 .../server/DataDomainProvider.java              |  7 +++++
 .../configuration/server/ServerModule.java      | 14 +++++++++
 .../reflect/LifecycleCallbackRegistry.java      | 24 ++++++----------
 .../server/DataDomainProviderTest.java          | 30 ++++++++++++++++----
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |  1 +
 6 files changed, 63 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/e68d4640/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java
index 091af8a..ce2efcf 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java
@@ -53,6 +53,13 @@ public interface Constants {
     String SERVER_DOMAIN_FILTERS_LIST = "cayenne.server.domain_filters";
 
     /**
+     * A DI container key for the List&lt;Object&gt; storing lifecycle events listeners.
+     *
+     * @see org.apache.cayenne.configuration.server.ServerModule#contributeDomainListeners(Binder).
+     */
+    String SERVER_DOMAIN_LISTENERS_LIST = "cayenne.server.domain_listeners";
+
+    /**
      * A DI container key for the List&lt;String&gt; storing locations of the
      * one of more project configuration files.
      */

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e68d4640/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
index c630155..67ad5d0 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
@@ -70,6 +70,9 @@ public class DataDomainProvider implements Provider<DataDomain> {
 	@Inject(Constants.SERVER_DOMAIN_FILTERS_LIST)
 	protected List<DataChannelFilter> filters;
 
+	@Inject(Constants.SERVER_DOMAIN_LISTENERS_LIST)
+	protected List<Object> listeners;
+
 	@Inject(Constants.SERVER_PROJECT_LOCATIONS_LIST)
 	protected List<String> locations;
 
@@ -153,6 +156,10 @@ public class DataDomainProvider implements Provider<DataDomain> {
 			dataDomain.addFilter(filter);
 		}
 
+		for (Object listener : listeners) {
+			dataDomain.addListener(listener);
+		}
+
 		return dataDomain;
 	}
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e68d4640/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
index 68c3757..61ba17b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
@@ -172,6 +172,17 @@ public class ServerModule implements Module {
     }
 
     /**
+     * Provides access to a DI collection builder for lifecycle events listeners.
+     *
+     * @param binder DI binder passed to the module during injector startup.
+     * @return ListBuilder for listener Objects.
+     * @since 4.0
+     */
+    public static ListBuilder<Object> contributeDomainListeners(Binder binder) {
+        return binder.bindList(Object.class, Constants.SERVER_DOMAIN_LISTENERS_LIST);
+    }
+
+    /**
      * Provides access to a DI collection builder for {@link DbAdapterDetector}'s that allows downstream modules to
      * "contribute" their own adapter detectors.
      *
@@ -285,6 +296,9 @@ public class ServerModule implements Module {
         // configure a filter chain with only one TransactionFilter as default
         contributeDomainFilters(binder).add(TransactionFilter.class);
 
+        // init listener list
+        contributeDomainListeners(binder);
+
         // configure extended types
         contributeDefaultTypes(binder).add(new VoidType()).add(new BigDecimalType())
                 .add(new BigIntegerType()).add(new BooleanType()).add(new ByteArrayType(false, true))

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e68d4640/cayenne-server/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java b/cayenne-server/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
index 9083f37..2dc60a2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
@@ -21,6 +21,7 @@ package org.apache.cayenne.reflect;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -160,8 +161,7 @@ public class LifecycleCallbackRegistry {
 	}
 
 	/**
-	 * @since 4.0 renamed to {@link #addCallback(LifecycleEvent, Class, String)}
-	 *        .
+	 * @since 4.0 renamed to {@link #addCallback(LifecycleEvent, Class, String)}.
 	 */
 	@Deprecated
 	public void addListener(LifecycleEvent type, Class<?> entityClass, String methodName) {
@@ -187,18 +187,14 @@ public class LifecycleCallbackRegistry {
 
 					if (reader != null) {
 
-						Set<Class<?>> types = new HashSet<Class<?>>();
+						Set<Class<?>> types = new HashSet<>();
 
 						Class<?>[] entities = reader.entities(a);
 						Class<? extends Annotation>[] entityAnnotations = reader.entityAnnotations(a);
 
-						for (Class<?> type : entities) {
-							// TODO: ignoring entity subclasses? whenever we add
-							// those,
-							// take
-							// into account "exlcudeSuperclassListeners" flag
-							types.add(type);
-						}
+						// TODO: ignoring entity subclasses?
+						// whenever we add those, take into account "exlcudeSuperclassListeners" flag
+						Collections.addAll(types, entities);
 
 						for (Class<? extends Annotation> type : entityAnnotations) {
 							types.addAll(getAnnotatedEntities(type));
@@ -400,7 +396,7 @@ public class LifecycleCallbackRegistry {
 		if (entities == null) {
 
 			// ensure no dupes
-			entities = new HashSet<Class<?>>();
+			entities = new HashSet<>();
 
 			for (ObjEntity entity : entityResolver.getObjEntities()) {
 				Class<?> entityType;
@@ -412,12 +408,10 @@ public class LifecycleCallbackRegistry {
 
 				// ensure that we don't register the same callback for multiple
 				// classes in the same hierarchy, so find the topmost type using
-				// a given
-				// annotation and register it once
+				// a given annotation and register it once
 
 				// TODO: This ignores "excludeSuperclassListeners" setting,
-				// which is
-				// not possible with annotations anyways
+				// which is not possible with annotations anyways
 
 				while (entityType != null && entityType.isAnnotationPresent(annotationType)) {
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e68d4640/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
index 3e96950..af236eb 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
@@ -20,6 +20,8 @@ package org.apache.cayenne.configuration.server;
 
 import org.apache.cayenne.ConfigurationException;
 import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.Persistent;
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.access.DataRowStoreFactory;
@@ -34,6 +36,7 @@ import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory;
 import org.apache.cayenne.access.translator.batch.DefaultBatchTranslatorFactory;
 import org.apache.cayenne.access.translator.select.DefaultSelectTranslatorFactory;
 import org.apache.cayenne.access.translator.select.SelectTranslatorFactory;
+import org.apache.cayenne.annotation.PostLoad;
 import org.apache.cayenne.ashwood.AshwoodEntitySorter;
 import org.apache.cayenne.cache.QueryCache;
 import org.apache.cayenne.configuration.ConfigurationNameMapper;
@@ -80,6 +83,7 @@ import org.apache.cayenne.log.CommonsJdbcEventLogger;
 import org.apache.cayenne.log.JdbcEventLogger;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.EntitySorter;
+import org.apache.cayenne.map.LifecycleEvent;
 import org.apache.cayenne.resource.ClassLoaderResourceLocator;
 import org.apache.cayenne.resource.Resource;
 import org.apache.cayenne.resource.ResourceLocator;
@@ -95,6 +99,8 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 public class DataDomainProviderTest {
 
@@ -131,11 +137,12 @@ public class DataDomainProviderTest {
 			@Override
 			public ConfigurationTree<DataChannelDescriptor> load(Resource configurationResource)
 					throws ConfigurationException {
-				return new ConfigurationTree<DataChannelDescriptor>(testDescriptor, null);
+				return new ConfigurationTree<>(testDescriptor, null);
 			}
 		};
 
 		final EventManager eventManager = new MockEventManager();
+		final TestListener mockListener = mock(TestListener.class);
 
 		Module testModule = new Module() {
 
@@ -153,6 +160,7 @@ public class DataDomainProviderTest {
 						.add(SybaseSniffer.class).add(DerbySniffer.class).add(SQLServerSniffer.class)
 						.add(OracleSniffer.class).add(PostgresSniffer.class).add(MySQLSniffer.class);
 				ServerModule.contributeDomainFilters(binder);
+				ServerModule.contributeDomainListeners(binder).add(mockListener);
 				ServerModule.contributeProjectLocations(binder).add(testConfigName);
 
 				// configure extended types
@@ -167,10 +175,8 @@ public class DataDomainProviderTest {
 				final ResourceLocator locator = new ClassLoaderResourceLocator(classLoaderManager) {
 
 					public Collection<Resource> findResources(String name) {
-						// ResourceLocator also used by JdbcAdapter to locate
-						// types.xml... if this is the request we are getting,
-						// just let
-						// it go through..
+						// ResourceLocator also used by JdbcAdapter to locate types.xml...
+						// if this is the request we are getting, just let it go through..
 						if (name.endsWith("types.xml")) {
 							return super.findResources(name);
 						}
@@ -248,5 +254,19 @@ public class DataDomainProviderTest {
 		assertEquals(SkipSchemaUpdateStrategy.class.getName(), node2.getSchemaUpdateStrategy().getClass().getName());
 
 		assertNotNull(node2.getAdapter());
+
+		// check that we have mock listener passed correctly
+		Persistent mockPersistent = mock(Persistent.class);
+		ObjectId mockObjectId = mock(ObjectId.class);
+		when(mockObjectId.getEntityName()).thenReturn("mock-entity-name");
+		when(mockPersistent.getObjectId()).thenReturn(mockObjectId);
+		domain.getEntityResolver().getCallbackRegistry().performCallbacks(LifecycleEvent.POST_LOAD, mockPersistent);
+		verify(mockListener).postLoadCallback(mockPersistent);
+	}
+
+	static class TestListener {
+		@PostLoad
+		public void postLoadCallback(Object object) {
+		}
 	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e68d4640/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt
index a107e5c..12c9533 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -16,6 +16,7 @@ Changes/New Features:
 CAY-1873 Move DataDomain cache configuration from the Modeler and into DI
 CAY-2258 DI: type-safe binding of List and Map
 CAY-2266 Move EventBridge implementations into autoloadable modules
+CAY-2267 Contribute lifecycle events listeners via DI
 
 Bug Fixes: