cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ntimof...@apache.org
Subject [1/3] cayenne git commit: Split DataChannelFilter into Query and Sync filters
Date Tue, 10 Jul 2018 13:54:23 GMT
Repository: cayenne
Updated Branches:
  refs/heads/master df5d38f7a -> a639980d2


Split DataChannelFilter into Query and Sync filters


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

Branch: refs/heads/master
Commit: 7475b4e09159e5fc5af8d9dadc1243bfb84b61aa
Parents: 22c2e78
Author: Nikita Timofeev <stariy95@gmail.com>
Authored: Tue May 29 18:36:41 2018 +0300
Committer: Nikita Timofeev <stariy95@gmail.com>
Committed: Fri Jun 8 16:18:26 2018 +0300

----------------------------------------------------------------------
 .../invalidation/CacheInvalidationFilter.java   |  44 ++---
 .../invalidation/CacheInvalidationModule.java   |   2 +-
 .../cayenne/commitlog/CommitLogFilter.java      |  22 +--
 .../commitlog/CommitLogModuleExtender.java      |   4 +-
 ...jectIdRelationshipBatchFaultingStrategy.java |   2 +-
 .../ObjectIdRelationshipFilter.java             |  30 +---
 .../ObjectIdRelationshipHandlerTest.java        |  14 +-
 .../org/apache/cayenne/DataChannelFilter.java   |  47 ++++--
 .../apache/cayenne/DataChannelFilterChain.java  |   9 +-
 .../apache/cayenne/DataChannelQueryFilter.java  |  32 ++++
 .../cayenne/DataChannelQueryFilterChain.java    |  31 ++++
 .../apache/cayenne/DataChannelSyncFilter.java   |  35 ++++
 .../org/apache/cayenne/access/DataDomain.java   | 168 +++++++++++++------
 .../apache/cayenne/configuration/Constants.java |   5 +-
 .../server/DataDomainProvider.java              |  28 ++++
 .../configuration/server/ServerModule.java      |  32 +++-
 .../apache/cayenne/tx/TransactionFilter.java    |  36 ++--
 .../apache/cayenne/MockDataChannelFilter.java   |  44 -----
 .../cayenne/access/DataDomainFiltersIT.java     | 143 +++++-----------
 .../server/DataDomainProviderTest.java          |   2 +
 .../unit/di/server/ServerCaseModule.java        |   4 +
 21 files changed, 413 insertions(+), 321 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationFilter.java
----------------------------------------------------------------------
diff --git a/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationFilter.java b/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationFilter.java
index 85063e7..2d7eb15 100644
--- a/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationFilter.java
+++ b/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationFilter.java
@@ -19,12 +19,10 @@
 
 package org.apache.cayenne.cache.invalidation;
 
-import org.apache.cayenne.DataChannel;
-import org.apache.cayenne.DataChannelFilter;
-import org.apache.cayenne.DataChannelFilterChain;
+import org.apache.cayenne.DataChannelSyncFilter;
+import org.apache.cayenne.DataChannelSyncFilterChain;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.Persistent;
-import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.annotation.PrePersist;
 import org.apache.cayenne.annotation.PreRemove;
 import org.apache.cayenne.annotation.PreUpdate;
@@ -32,7 +30,6 @@ import org.apache.cayenne.cache.QueryCache;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.Provider;
 import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.query.Query;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -45,7 +42,7 @@ import java.util.function.Function;
 
 /**
  * <p>
- * A {@link DataChannelFilter} that invalidates cache groups.
+ * A {@link DataChannelSyncFilter} that invalidates cache groups.
  * Use custom rules for invalidation provided via DI.
  * </p>
  * <p>
@@ -62,7 +59,7 @@ import java.util.function.Function;
  * @see InvalidationHandler
  * @since 4.0 enhanced to support custom handlers.
  */
-public class CacheInvalidationFilter implements DataChannelFilter {
+public class CacheInvalidationFilter implements DataChannelSyncFilter {
 
     private final Provider<QueryCache> cacheProvider;
     private final List<InvalidationHandler> handlers;
@@ -78,16 +75,9 @@ public class CacheInvalidationFilter implements DataChannelFilter {
         this.handlers = handlers;
     }
 
-    public void init(DataChannel channel) {
-        // noop
-    }
-
-    public QueryResponse onQuery(ObjectContext originatingContext, Query query, DataChannelFilterChain filterChain) {
-        return filterChain.onQuery(originatingContext, query);
-    }
-
+    @Override
     public GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes,
-                            int syncType, DataChannelFilterChain filterChain) {
+                            int syncType, DataChannelSyncFilterChain filterChain) {
         try {
             GraphDiff result = filterChain.onSync(originatingContext, changes, syncType);
             // no exceptions, flush...
@@ -118,18 +108,16 @@ public class CacheInvalidationFilter implements DataChannelFilter {
         // TODO: for some reason we can't use Persistent as the argument type... (is it fixed in Cayenne 4.0.M4?)
         Persistent p = (Persistent) object;
 
-        Function<Persistent, Collection<CacheGroupDescriptor>> invalidationFunction = mappedHandlers.get(p.getClass());
-        if (invalidationFunction == null) {
-            invalidationFunction = skipHandler;
-            for (InvalidationHandler handler : handlers) {
-                Function<Persistent, Collection<CacheGroupDescriptor>> function = handler.canHandle(p.getClass());
-                if (function != null) {
-                    invalidationFunction = function;
-                    break;
-                }
-            }
-            mappedHandlers.put(p.getClass(), invalidationFunction);
-        }
+        Function<Persistent, Collection<CacheGroupDescriptor>> invalidationFunction = mappedHandlers
+                .computeIfAbsent(p.getClass(), cl -> {
+                    for (InvalidationHandler handler : handlers) {
+                        Function<Persistent, Collection<CacheGroupDescriptor>> function = handler.canHandle(cl);
+                        if (function != null) {
+                            return function;
+                        }
+                    }
+                    return skipHandler;
+                });
 
         Collection<CacheGroupDescriptor> objectGroups = invalidationFunction.apply(p);
         if (!objectGroups.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationModule.java
----------------------------------------------------------------------
diff --git a/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationModule.java b/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationModule.java
index 822dbc6..2460a99 100644
--- a/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationModule.java
+++ b/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/cache/invalidation/CacheInvalidationModule.java
@@ -52,7 +52,7 @@ public class CacheInvalidationModule implements Module {
         contributeInvalidationHandler(binder).add(CacheGroupsHandler.class);
 
         // want the filter to be INSIDE transaction by default
-        ServerModule.contributeDomainFilters(binder)
+        ServerModule.contributeDomainSyncFilters(binder)
                 .insertBefore(CacheInvalidationFilter.class, TransactionFilter.class);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogFilter.java
----------------------------------------------------------------------
diff --git a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogFilter.java b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogFilter.java
index a3c8a30..b383dc2 100644
--- a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogFilter.java
+++ b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogFilter.java
@@ -22,25 +22,23 @@ import java.util.Collection;
 import java.util.List;
 
 import org.apache.cayenne.DataChannel;
-import org.apache.cayenne.DataChannelFilter;
-import org.apache.cayenne.DataChannelFilterChain;
+import org.apache.cayenne.DataChannelSyncFilter;
+import org.apache.cayenne.DataChannelSyncFilterChain;
 import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.graph.GraphChangeHandler;
 import org.apache.cayenne.graph.GraphDiff;
 import org.apache.cayenne.commitlog.model.ChangeMap;
 import org.apache.cayenne.commitlog.model.MutableChangeMap;
 import org.apache.cayenne.commitlog.meta.CommitLogEntityFactory;
-import org.apache.cayenne.query.Query;
 
 /**
- * A {@link DataChannelFilter} that captures commit changes, delegating their
+ * A {@link DataChannelSyncFilter} that captures commit changes, delegating their
  * processing to an underlying collection of listeners.
  * 
  * @since 4.0
  */
-public class CommitLogFilter implements DataChannelFilter {
+public class CommitLogFilter implements DataChannelSyncFilter {
 
 	private CommitLogEntityFactory entityFactory;
 	private Collection<CommitLogListener> listeners;
@@ -52,18 +50,8 @@ public class CommitLogFilter implements DataChannelFilter {
 	}
 
 	@Override
-	public void init(DataChannel channel) {
-		// do nothing...
-	}
-
-	@Override
-	public QueryResponse onQuery(ObjectContext originatingContext, Query query, DataChannelFilterChain filterChain) {
-		return filterChain.onQuery(originatingContext, query);
-	}
-
-	@Override
 	public GraphDiff onSync(ObjectContext originatingContext, GraphDiff beforeDiff, int syncType,
-			DataChannelFilterChain filterChain) {
+							DataChannelSyncFilterChain filterChain) {
 
 		// process commits only; skip rollback
 		if (syncType != DataChannel.FLUSH_CASCADE_SYNC && syncType != DataChannel.FLUSH_NOCASCADE_SYNC) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogModuleExtender.java
----------------------------------------------------------------------
diff --git a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogModuleExtender.java b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogModuleExtender.java
index 558dcba..3c96a48 100644
--- a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogModuleExtender.java
+++ b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogModuleExtender.java
@@ -115,9 +115,9 @@ public class CommitLogModuleExtender {
             }
 
             if (excludeFromTransaction) {
-                ServerModule.contributeDomainFilters(binder).addAfter(CommitLogFilter.class, TransactionFilter.class);
+                ServerModule.contributeDomainSyncFilters(binder).addAfter(CommitLogFilter.class, TransactionFilter.class);
             } else {
-                ServerModule.contributeDomainFilters(binder).insertBefore(CommitLogFilter.class, TransactionFilter.class);
+                ServerModule.contributeDomainSyncFilters(binder).insertBefore(CommitLogFilter.class, TransactionFilter.class);
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipBatchFaultingStrategy.java
----------------------------------------------------------------------
diff --git a/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipBatchFaultingStrategy.java b/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipBatchFaultingStrategy.java
index 4499880..506fbcd 100644
--- a/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipBatchFaultingStrategy.java
+++ b/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipBatchFaultingStrategy.java
@@ -35,7 +35,7 @@ public class ObjectIdRelationshipBatchFaultingStrategy implements
     private ThreadLocal<List<ObjectIdBatchSourceItem>> batchSources;
 
     public ObjectIdRelationshipBatchFaultingStrategy() {
-        this.batchSources = new ThreadLocal<List<ObjectIdBatchSourceItem>>();
+        this.batchSources = new ThreadLocal<>();
     }
 
     public void afterObjectLoaded(DataObject object) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipFilter.java
----------------------------------------------------------------------
diff --git a/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipFilter.java b/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipFilter.java
index 957c093..bf7bb88 100644
--- a/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipFilter.java
+++ b/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipFilter.java
@@ -18,28 +18,26 @@
  ****************************************************************/
 package org.apache.cayenne.lifecycle.relationship;
 
-import org.apache.cayenne.DataChannel;
-import org.apache.cayenne.DataChannelFilter;
-import org.apache.cayenne.DataChannelFilterChain;
+import org.apache.cayenne.DataChannelQueryFilter;
+import org.apache.cayenne.DataChannelQueryFilterChain;
 import org.apache.cayenne.DataObject;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.annotation.PostLoad;
 import org.apache.cayenne.annotation.PostPersist;
 import org.apache.cayenne.annotation.PostUpdate;
-import org.apache.cayenne.graph.GraphDiff;
 import org.apache.cayenne.query.Query;
 
 /**
- * A {@link DataChannelFilter} that implements ObjectId relationships read functionality.
+ * A {@link DataChannelQueryFilter} that implements ObjectId relationships read functionality.
  * 
  * @since 3.1
  */
-public class ObjectIdRelationshipFilter implements DataChannelFilter {
+public class ObjectIdRelationshipFilter implements DataChannelQueryFilter {
 
     private ObjectIdRelationshipFaultingStrategy faultingStrategy;
 
-    public void init(DataChannel channel) {
+    public ObjectIdRelationshipFilter() {
         this.faultingStrategy = createFaultingStrategy();
     }
 
@@ -47,24 +45,10 @@ public class ObjectIdRelationshipFilter implements DataChannelFilter {
         return new ObjectIdRelationshipBatchFaultingStrategy();
     }
 
-    public GraphDiff onSync(
-            ObjectContext context,
-            GraphDiff diff,
-            int syncType,
-            DataChannelFilterChain chain) {
-        // noop ... all work is done via listeners...
-        return chain.onSync(context, diff, syncType);
-    }
-
-    public QueryResponse onQuery(
-            ObjectContext context,
-            Query query,
-            DataChannelFilterChain chain) {
-
+    public QueryResponse onQuery(ObjectContext context, Query query, DataChannelQueryFilterChain chain) {
         try {
             return chain.onQuery(context, query);
-        }
-        finally {
+        } finally {
             faultingStrategy.afterQuery();
         }
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipHandlerTest.java
----------------------------------------------------------------------
diff --git a/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipHandlerTest.java b/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipHandlerTest.java
index 8cbcdb7..4c21d74 100644
--- a/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipHandlerTest.java
+++ b/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/relationship/ObjectIdRelationshipHandlerTest.java
@@ -32,7 +32,7 @@ import org.junit.Before;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertSame;
 
 public class ObjectIdRelationshipHandlerTest {
@@ -48,9 +48,8 @@ public class ObjectIdRelationshipHandlerTest {
 
         // a filter is required to invalidate root objects after commit
         ObjectIdRelationshipFilter filter = new ObjectIdRelationshipFilter();
-        runtime.getDataDomain().addFilter(filter);
-        runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(
-                filter);
+        runtime.getDataDomain().addQueryFilter(filter);
+        runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(filter);
 
         DBHelper dbHelper = new DBHelper(runtime.getDataSource(null));
 
@@ -62,7 +61,7 @@ public class ObjectIdRelationshipHandlerTest {
     }
 
     @After
-    public void tearDown() throws Exception {
+    public void tearDown() {
         runtime.shutdown();
     }
 
@@ -76,8 +75,7 @@ public class ObjectIdRelationshipHandlerTest {
 
         UuidRoot1 r1 = context.newObject(UuidRoot1.class);
 
-        IdCoder refHandler = new IdCoder(context
-                .getEntityResolver());
+        IdCoder refHandler = new IdCoder(context.getEntityResolver());
         ObjectIdRelationshipHandler handler = new ObjectIdRelationshipHandler(refHandler);
         handler.relate(r1, e1);
 
@@ -137,7 +135,7 @@ public class ObjectIdRelationshipHandlerTest {
         context.commitChanges();
 
         int id = Cayenne.intPKForObject(e1);
-        assertFalse(1 == id);
+        assertNotEquals(1, id);
 
         Object[] r1x = rootTable.select();
         assertEquals("E1:" + id, r1x[1]);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilter.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilter.java b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilter.java
index 585d01b..24d625c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilter.java
@@ -28,19 +28,44 @@ import org.apache.cayenne.query.Query;
  * etc.
  * 
  * @since 3.1
+ * @deprecated since 4.1 use {@link DataChannelQueryFilter} and {@link DataChannelSyncFilter}
  */
-public interface DataChannelFilter {
-    
+@Deprecated
+public interface DataChannelFilter extends DataChannelSyncFilter, DataChannelQueryFilter {
+
     void init(DataChannel channel);
 
-    QueryResponse onQuery(
-            ObjectContext originatingContext,
-            Query query,
-            DataChannelFilterChain filterChain);
+    QueryResponse onQuery(ObjectContext originatingContext, Query query,
+                          DataChannelFilterChain filterChain);
+
+    GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes, int syncType,
+                     DataChannelFilterChain filterChain);
+
+    /**
+     * Adapter method that allows to use old DataChannelFilter as new query filter
+     */
+    @Override
+    default QueryResponse onQuery(ObjectContext originatingContext, Query query,
+                                  DataChannelQueryFilterChain filterChain) {
+        return onQuery(originatingContext, query, new DataChannelFilterChain(){
+            @Override
+            public QueryResponse onQuery(ObjectContext originatingContext, Query query) {
+                return filterChain.onQuery(originatingContext, query);
+            }
+        });
+    }
 
-    GraphDiff onSync(
-            ObjectContext originatingContext,
-            GraphDiff changes,
-            int syncType,
-            DataChannelFilterChain filterChain);
+    /**
+     * Adapter method that allows to use old DataChannelFilter as new sync filter
+     */
+    @Override
+    default GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes, int syncType,
+                             DataChannelSyncFilterChain filterChain) {
+        return onSync(originatingContext, changes, syncType, new DataChannelFilterChain(){
+            @Override
+            public GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes, int syncType) {
+                return filterChain.onSync(originatingContext, changes, syncType);
+            }
+        });
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilterChain.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilterChain.java b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilterChain.java
index 594c3a7..20d554d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilterChain.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelFilterChain.java
@@ -26,10 +26,15 @@ import org.apache.cayenne.query.Query;
  * the underlying DataChannel for the last chain filter.
  * 
  * @since 3.1
+ * @deprecated since 4.1 in favor of {@link DataChannelSyncFilterChain} and {@link DataChannelQueryFilterChain}
  */
 public interface DataChannelFilterChain {
 
-    QueryResponse onQuery(ObjectContext originatingContext, Query query);
+    default QueryResponse onQuery(ObjectContext originatingContext, Query query) {
+        throw new UnsupportedOperationException();
+    }
 
-    GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes, int syncType);
+    default GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes, int syncType) {
+        throw new UnsupportedOperationException();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/main/java/org/apache/cayenne/DataChannelQueryFilter.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/DataChannelQueryFilter.java b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelQueryFilter.java
new file mode 100644
index 0000000..04f0ef1
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelQueryFilter.java
@@ -0,0 +1,32 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.cayenne;
+
+import org.apache.cayenne.query.Query;
+
+/**
+ * @since 4.1
+ */
+@FunctionalInterface
+public interface DataChannelQueryFilter {
+
+    QueryResponse onQuery(ObjectContext originatingContext, Query query, DataChannelQueryFilterChain filterChain);
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/main/java/org/apache/cayenne/DataChannelQueryFilterChain.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/DataChannelQueryFilterChain.java b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelQueryFilterChain.java
new file mode 100644
index 0000000..322d9d2
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelQueryFilterChain.java
@@ -0,0 +1,31 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.cayenne;
+
+import org.apache.cayenne.query.Query;
+
+/**
+ * @since 4.1
+ */
+public interface DataChannelQueryFilterChain {
+
+    QueryResponse onQuery(ObjectContext originatingContext, Query query);
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/main/java/org/apache/cayenne/DataChannelSyncFilter.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/DataChannelSyncFilter.java b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelSyncFilter.java
new file mode 100644
index 0000000..96f1cdd
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/DataChannelSyncFilter.java
@@ -0,0 +1,35 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.cayenne;
+
+import org.apache.cayenne.graph.GraphDiff;
+
+/**
+ * @since 4.1
+ */
+public interface DataChannelSyncFilter {
+
+    GraphDiff onSync(
+            ObjectContext originatingContext,
+            GraphDiff changes,
+            int syncType,
+            DataChannelSyncFilterChain filterChain);
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java
index bb68fdb..ecd0938 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java
@@ -22,7 +22,10 @@ package org.apache.cayenne.access;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataChannel;
 import org.apache.cayenne.DataChannelFilter;
-import org.apache.cayenne.DataChannelFilterChain;
+import org.apache.cayenne.DataChannelQueryFilter;
+import org.apache.cayenne.DataChannelQueryFilterChain;
+import org.apache.cayenne.DataChannelSyncFilter;
+import org.apache.cayenne.DataChannelSyncFilterChain;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.cache.QueryCache;
@@ -91,9 +94,21 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	/**
 	 * @since 3.1
+	 * @deprecated since 4.1 this field is unused
 	 */
+	@Deprecated
 	protected List<DataChannelFilter> filters;
 
+	/**
+	 * @since 4.1
+	 */
+	protected List<DataChannelQueryFilter> queryFilters;
+
+	/**
+	 * @since 4.1
+	 */
+	protected List<DataChannelSyncFilter> syncFilters;
+
 	protected Map<String, DataNode> nodes;
 	protected Map<String, DataNode> nodesByDataMapName;
 	protected DataNode defaultNode;
@@ -146,7 +161,8 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	private void init(String name) {
 
-		this.filters = new CopyOnWriteArrayList<>();
+		this.queryFilters = new CopyOnWriteArrayList<>();
+		this.syncFilters = new CopyOnWriteArrayList<>();
 		this.nodesByDataMapName = new ConcurrentHashMap<>();
 		this.nodes = new ConcurrentHashMap<>();
 
@@ -388,15 +404,8 @@ public class DataDomain implements QueryEngine, DataChannel {
 	public void removeDataNode(String nodeName) {
 		DataNode removed = nodes.remove(nodeName);
 		if (removed != null) {
-
 			removed.setEntityResolver(null);
-
-			Iterator<DataNode> it = nodesByDataMapName.values().iterator();
-			while (it.hasNext()) {
-				if (it.next() == removed) {
-					it.remove();
-				}
-			}
+			nodesByDataMapName.values().removeIf(dataNode -> dataNode == removed);
 		}
 	}
 
@@ -520,13 +529,9 @@ public class DataDomain implements QueryEngine, DataChannel {
 	 * Routes queries to appropriate DataNodes for execution.
 	 */
 	public void performQueries(final Collection<? extends Query> queries, final OperationObserver callback) {
-
-		transactionManager.performInTransaction(new TransactionalOperation<Object>() {
-			@Override
-			public Object perform() {
-				new DataDomainLegacyQueryAction(DataDomain.this, new QueryChain(queries), callback).execute();
-				return null;
-			}
+		transactionManager.performInTransaction(() -> {
+			new DataDomainLegacyQueryAction(DataDomain.this, new QueryChain(queries), callback).execute();
+			return null;
 		});
 	}
 
@@ -667,16 +672,40 @@ public class DataDomain implements QueryEngine, DataChannel {
 	}
 
 	/**
-	 * Returns an unmodifiable list of filters registered with this DataDomain.
+	 * Since 4.1 returns empty list.
+	 *
+	 * @since 3.1
+	 * @deprecated since 4.1 use {@link #getQueryFilters()} and {@link #getSyncFilters()}
+	 */
+	@Deprecated
+	public List<DataChannelFilter> getFilters() {
+		return Collections.emptyList();
+	}
+
+	/**
+	 * Returns an unmodifiable list of query filters registered with this DataDomain.
 	 * <p>
 	 * Filter ordering note: filters are applied in reverse order of their
 	 * occurrence in the filter list. I.e. the last filter in the list called
 	 * first in the chain.
 	 *
-	 * @since 3.1
+	 * @since 4.1
 	 */
-	public List<DataChannelFilter> getFilters() {
-		return Collections.unmodifiableList(filters);
+	public List<DataChannelQueryFilter> getQueryFilters() {
+		return Collections.unmodifiableList(queryFilters);
+	}
+
+	/**
+	 * Returns an unmodifiable list of sync filters registered with this DataDomain.
+	 * <p>
+	 * Filter ordering note: filters are applied in reverse order of their
+	 * occurrence in the filter list. I.e. the last filter in the list called
+	 * first in the chain.
+	 *
+	 * @since 4.1
+	 */
+	public List<DataChannelSyncFilter> getSyncFilters() {
+		return Collections.unmodifiableList(syncFilters);
 	}
 
 	/**
@@ -685,20 +714,66 @@ public class DataDomain implements QueryEngine, DataChannel {
 	 * methods have event annotations.
 	 *
 	 * @since 3.1
+	 * @deprecated since 4.1 use {@link #addQueryFilter(DataChannelQueryFilter)} and {@link #addSyncFilter(DataChannelSyncFilter)} instead
 	 */
+	@Deprecated
 	public void addFilter(DataChannelFilter filter) {
 		filter.init(this);
-		getEntityResolver().getCallbackRegistry().addListener(filter);
-		filters.add(filter);
+		addListener(filter);
+		queryFilters.add(filter);
+		syncFilters.add(filter);
+	}
+
+	/**
+	 * Adds a new query filter.
+	 * Also registers passed filter as an event listener, if any of its methods have event annotations.
+	 *
+	 * @since 4.1
+	 */
+	public void addQueryFilter(DataChannelQueryFilter filter) {
+		addListener(filter);
+		queryFilters.add(filter);
+	}
+
+	/**
+	 * Adds a new sync filter.
+	 * Also registers passed filter as an event listener, if any of its methods have event annotations.
+	 *
+	 * @since 4.1
+	 */
+	public void addSyncFilter(DataChannelSyncFilter filter) {
+		addListener(filter);
+		syncFilters.add(filter);
 	}
 
 	/**
 	 * Removes a filter from the filter chain.
 	 *
 	 * @since 3.1
+	 * @deprecated since 4.1 use {@link #removeQueryFilter(DataChannelQueryFilter)} and {@link #removeSyncFilter(DataChannelSyncFilter)} instead
 	 */
+	@Deprecated
 	public void removeFilter(DataChannelFilter filter) {
-		filters.remove(filter);
+		removeQueryFilter(filter);
+		removeSyncFilter(filter);
+	}
+
+	/**
+	 * Removes a query filter from the filter chain.
+	 *
+	 * @since 4.1
+	 */
+	public void removeQueryFilter(DataChannelQueryFilter filter) {
+		queryFilters.remove(filter);
+	}
+
+	/**
+	 * Removes a sync filter from the filter chain.
+	 *
+	 * @since 4.1
+	 */
+	public void removeSyncFilter(DataChannelSyncFilter filter) {
+		syncFilters.remove(filter);
 	}
 
 	/**
@@ -712,50 +787,35 @@ public class DataDomain implements QueryEngine, DataChannel {
 		getEntityResolver().getCallbackRegistry().addListener(listener);
 	}
 
-	abstract class DataDomainFilterChain implements DataChannelFilterChain {
+	final class DataDomainQueryFilterChain implements DataChannelQueryFilterChain {
 
-		private int i;
-
-		DataDomainFilterChain() {
-			i = filters != null ? filters.size() : 0;
-		}
+		private int idx;
 
-		DataChannelFilter nextFilter() {
-			// filters are ordered innermost to outermost
-			i--;
-			return i >= 0 ? filters.get(i) : null;
+		DataDomainQueryFilterChain() {
+			idx = queryFilters.size();
 		}
-	}
-
-	final class DataDomainQueryFilterChain extends DataDomainFilterChain {
 
 		@Override
 		public QueryResponse onQuery(ObjectContext originatingContext, Query query) {
-
-			DataChannelFilter filter = nextFilter();
-			return (filter != null) ? filter.onQuery(originatingContext, query, this) : onQueryNoFilters(
-					originatingContext, query);
-		}
-
-		@Override
-		public GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes, int syncType) {
-			throw new UnsupportedOperationException("It is illegal to call 'onSync' inside 'onQuery' chain");
+			return --idx >= 0
+					? queryFilters.get(idx).onQuery(originatingContext, query, this)
+					: onQueryNoFilters(originatingContext, query);
 		}
 	}
 
-	final class DataDomainSyncFilterChain extends DataDomainFilterChain {
+	final class DataDomainSyncFilterChain implements DataChannelSyncFilterChain {
 
-		@Override
-		public GraphDiff onSync(final ObjectContext originatingContext, final GraphDiff changes, int syncType) {
+		private int idx;
 
-			DataChannelFilter filter = nextFilter();
-			return (filter != null) ? filter.onSync(originatingContext, changes, syncType, this) : onSyncNoFilters(
-					originatingContext, changes, syncType);
+		DataDomainSyncFilterChain() {
+			idx = syncFilters.size();
 		}
 
 		@Override
-		public QueryResponse onQuery(ObjectContext originatingContext, Query query) {
-			throw new UnsupportedOperationException("It is illegal to call 'onQuery' inside 'onSync' chain");
+		public GraphDiff onSync(ObjectContext originatingContext, final GraphDiff changes, int syncType) {
+			return --idx >= 0
+					? syncFilters.get(idx).onSync(originatingContext, changes, syncType, this)
+					: onSyncNoFilters(originatingContext, changes, syncType);
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/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 2704ae4..7eb45dc 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
@@ -48,8 +48,11 @@ public interface Constants {
      * A DI container key for the List&lt;DataChannelFilter&gt; storing
      * DataDomain filters.
      *
-     * @see org.apache.cayenne.configuration.server.ServerModule#contributeDomainFilters(Binder).
+     * @see org.apache.cayenne.configuration.server.ServerModule#contributeDomainQueryFilters(Binder)
+     * @see org.apache.cayenne.configuration.server.ServerModule#contributeDomainSyncFilters(Binder)
+     * @deprecated since 4.1 domain filters replaced with query and sync filters
      */
+    @Deprecated
     String SERVER_DOMAIN_FILTERS_LIST = "cayenne.server.domain_filters";
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/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 f0d3402..26573d1 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
@@ -21,6 +21,8 @@ package org.apache.cayenne.configuration.server;
 import org.apache.cayenne.ConfigurationException;
 import org.apache.cayenne.DataChannel;
 import org.apache.cayenne.DataChannelFilter;
+import org.apache.cayenne.DataChannelQueryFilter;
+import org.apache.cayenne.DataChannelSyncFilter;
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.access.DataRowStoreFactory;
@@ -68,9 +70,25 @@ public class DataDomainProvider implements Provider<DataDomain> {
 	@Inject
 	protected DataChannelDescriptorLoader loader;
 
+	/**
+	 * @deprecated since 4.1, use query and sync filters instead
+	 */
+	@Deprecated
 	@Inject(Constants.SERVER_DOMAIN_FILTERS_LIST)
 	protected List<DataChannelFilter> filters;
 
+	/**
+	 * @since 4.1
+	 */
+	@Inject
+	protected List<DataChannelQueryFilter> queryFilters;
+
+	/**
+	 * @since 4.1
+	 */
+	@Inject
+	protected List<DataChannelSyncFilter> syncFilters;
+
 	@Inject(Constants.SERVER_DOMAIN_LISTENERS_LIST)
 	protected List<Object> listeners;
 
@@ -110,6 +128,7 @@ public class DataDomainProvider implements Provider<DataDomain> {
 		return new DataDomain(name);
 	}
 
+	@SuppressWarnings("deprecation")
 	protected DataDomain createAndInitDataDomain() throws Exception {
 
 		DataChannelDescriptor descriptor = loadDescriptor();
@@ -156,10 +175,19 @@ public class DataDomainProvider implements Provider<DataDomain> {
 			dataDomain.setDefaultNode(defaultNode);
 		}
 
+		// filters are deprecated, used here for backward compatibility
 		for (DataChannelFilter filter : filters) {
 			dataDomain.addFilter(filter);
 		}
 
+		for (DataChannelQueryFilter filter : queryFilters) {
+			dataDomain.addQueryFilter(filter);
+		}
+
+		for (DataChannelSyncFilter filter : syncFilters) {
+			dataDomain.addSyncFilter(filter);
+		}
+
 		for (Object listener : listeners) {
 			dataDomain.addListener(listener);
 		}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/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 39e8c14..3a1987d 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
@@ -20,6 +20,8 @@ package org.apache.cayenne.configuration.server;
 
 import org.apache.cayenne.DataChannel;
 import org.apache.cayenne.DataChannelFilter;
+import org.apache.cayenne.DataChannelQueryFilter;
+import org.apache.cayenne.DataChannelSyncFilter;
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataRowStoreFactory;
 import org.apache.cayenne.access.DefaultDataRowStoreFactory;
@@ -202,12 +204,38 @@ public class ServerModule implements Module {
      * @param binder DI binder passed to the module during injector startup.
      * @return ListBuilder for DataChannelFilter.
      * @since 4.0
+     * @deprecated since 4.1 use {@link #contributeDomainQueryFilters(Binder)} and {@link #contributeDomainSyncFilters(Binder)}
      */
+    @Deprecated
     public static ListBuilder<DataChannelFilter> contributeDomainFilters(Binder binder) {
         return binder.bindList(DataChannelFilter.class, Constants.SERVER_DOMAIN_FILTERS_LIST);
     }
 
     /**
+     * Provides access to a DI collection builder for {@link DataChannelQueryFilter}'s that allows downstream modules to
+     * "contribute" their own DataDomain query filters
+     *
+     * @param binder DI binder passed to the module during injector startup.
+     * @return ListBuilder for DataChannelQueryFilter.
+     * @since 4.1
+     */
+    public static ListBuilder<DataChannelQueryFilter> contributeDomainQueryFilters(Binder binder) {
+        return binder.bindList(DataChannelQueryFilter.class);
+    }
+
+    /**
+     * Provides access to a DI collection builder for {@link DataChannelSyncFilter}'s that allows downstream modules to
+     * "contribute" their own DataDomain sync filters
+     *
+     * @param binder DI binder passed to the module during injector startup.
+     * @return ListBuilder for DataChannelSyncFilter.
+     * @since 4.1
+     */
+    public static ListBuilder<DataChannelSyncFilter> contributeDomainSyncFilters(Binder binder) {
+        return binder.bindList(DataChannelSyncFilter.class);
+    }
+
+    /**
      * Provides access to a DI collection builder for lifecycle events listeners.
      *
      * @param binder DI binder passed to the module during injector startup.
@@ -358,7 +386,9 @@ public class ServerModule implements Module {
                 .put(SybaseAdapter.class.getName(), SybasePkGenerator.class);
 
         // configure a filter chain with only one TransactionFilter as default
-        contributeDomainFilters(binder).add(TransactionFilter.class);
+        contributeDomainFilters(binder);
+        contributeDomainQueryFilters(binder);
+        contributeDomainSyncFilters(binder).add(TransactionFilter.class);
 
         // init listener list
         contributeDomainListeners(binder);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/main/java/org/apache/cayenne/tx/TransactionFilter.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/tx/TransactionFilter.java b/cayenne-server/src/main/java/org/apache/cayenne/tx/TransactionFilter.java
index 622f132..25b23a1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/tx/TransactionFilter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/tx/TransactionFilter.java
@@ -21,60 +21,46 @@ package org.apache.cayenne.tx;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataChannel;
-import org.apache.cayenne.DataChannelFilter;
-import org.apache.cayenne.DataChannelFilterChain;
 import org.apache.cayenne.DataChannelSyncCallbackAction;
+import org.apache.cayenne.DataChannelSyncFilter;
+import org.apache.cayenne.DataChannelSyncFilterChain;
 import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.query.Query;
 
 /**
- * A {@link DataChannelFilter} that provides transactions.
+ * A {@link DataChannelSyncFilter} that provides transactions.
  *
  * @since 4.0
  */
-public class TransactionFilter implements DataChannelFilter {
+public class TransactionFilter implements DataChannelSyncFilter {
 
     @Inject
     protected TransactionManager transactionManager;
 
     @Override
-    public void init(DataChannel channel) {
-    }
-
-    @Override
-    public QueryResponse onQuery(ObjectContext originatingContext, Query query, DataChannelFilterChain filterChain) {
-        return filterChain.onQuery(originatingContext, query);
-    }
-
-    @Override
-    public GraphDiff onSync(final ObjectContext originatingContext, final GraphDiff changes, final int syncType, final DataChannelFilterChain filterChain) {
+    public GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes, int syncType, DataChannelSyncFilterChain filterChain) {
         DataChannelSyncCallbackAction callbackAction = DataChannelSyncCallbackAction.getCallbackAction(
                 originatingContext.getChannel().getEntityResolver().getCallbackRegistry(),
                 originatingContext.getGraphManager(),
-                changes, syncType);
+                changes,
+                syncType
+        );
 
         callbackAction.applyPreCommit();
 
         GraphDiff result;
         switch (syncType) {
             case DataChannel.ROLLBACK_CASCADE_SYNC:
-                result = filterChain.onSync(originatingContext, changes, syncType);;
+                result = filterChain.onSync(originatingContext, changes, syncType);
                 break;
 
             // including transaction handling logic
             case DataChannel.FLUSH_NOCASCADE_SYNC:
             case DataChannel.FLUSH_CASCADE_SYNC:
-                result = transactionManager.performInTransaction(new TransactionalOperation<GraphDiff>() {
-                    @Override
-                    public GraphDiff perform() {
-                        return filterChain.onSync(originatingContext, changes, syncType);
-                    }
-                });
-
+                result = transactionManager.performInTransaction(() -> filterChain.onSync(originatingContext, changes, syncType));
                 break;
+
             default:
                 throw new CayenneRuntimeException("Invalid synchronization type: %d", syncType);
         }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/test/java/org/apache/cayenne/MockDataChannelFilter.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/MockDataChannelFilter.java b/cayenne-server/src/test/java/org/apache/cayenne/MockDataChannelFilter.java
deleted file mode 100644
index 85145be..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/MockDataChannelFilter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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.apache.cayenne;
-
-import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.query.Query;
-
-public class MockDataChannelFilter implements DataChannelFilter {
-
-    public void init(DataChannel channel) {
-    }
-
-    public QueryResponse onQuery(
-            ObjectContext originatingContext,
-            Query query,
-            DataChannelFilterChain filterChain) {
-        return null;
-    }
-
-    public GraphDiff onSync(
-            ObjectContext originatingContext,
-            GraphDiff changes,
-            int syncType,
-            DataChannelFilterChain filterChain) {
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/test/java/org/apache/cayenne/access/DataDomainFiltersIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataDomainFiltersIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataDomainFiltersIT.java
index 8e84fd0..c63e13e 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataDomainFiltersIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataDomainFiltersIT.java
@@ -18,15 +18,13 @@
  ****************************************************************/
 package org.apache.cayenne.access;
 
-import org.apache.cayenne.DataChannelFilter;
-import org.apache.cayenne.DataChannelFilterChain;
-import org.apache.cayenne.MockDataChannelFilter;
+import org.apache.cayenne.DataChannelQueryFilter;
+import org.apache.cayenne.DataChannelSyncFilter;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.configuration.server.ServerRuntime;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.testdo.testmap.Artist;
 import org.apache.cayenne.unit.di.server.CayenneProjects;
@@ -53,53 +51,36 @@ public class DataDomainFiltersIT extends ServerCase {
 
     @Test
     public void testDefaultFilters() {
-
         // There is a default TransactionFilter
         DataDomain domain = runtime.getDataDomain();
-        assertEquals(1, domain.filters.size());
+        assertEquals(0, domain.queryFilters.size());
+        assertEquals(1, domain.syncFilters.size());
     }
 
     @Test
     public void testOnQuery_FilterOrdering() {
 
         DataDomain domain = runtime.getDataDomain();
+        List<String> results = new ArrayList<>();
 
-        final List<String> results = new ArrayList<String>();
-
-        DataChannelFilter f1 = new MockDataChannelFilter() {
-
-            @Override
-            public QueryResponse onQuery(
-                    ObjectContext originatingContext,
-                    Query query,
-                    DataChannelFilterChain filterChain) {
-
-                results.add("f1start");
-                QueryResponse response = filterChain.onQuery(originatingContext, query);
-                results.add("f1end");
-                return response;
-            }
+        DataChannelQueryFilter f1 = (originatingContext, query, filterChain) -> {
+            results.add("f1start");
+            QueryResponse response = filterChain.onQuery(originatingContext, query);
+            results.add("f1end");
+            return response;
         };
 
-        DataChannelFilter f2 = new MockDataChannelFilter() {
-
-            @Override
-            public QueryResponse onQuery(
-                    ObjectContext originatingContext,
-                    Query query,
-                    DataChannelFilterChain filterChain) {
-
-                results.add("f2start");
-                QueryResponse response = filterChain.onQuery(originatingContext, query);
-                results.add("f2end");
-                return response;
-            }
+        DataChannelQueryFilter f2 = (originatingContext, query, filterChain) -> {
+            results.add("f2start");
+            QueryResponse response = filterChain.onQuery(originatingContext, query);
+            results.add("f2end");
+            return response;
         };
 
-        domain.filters.add(f1);
-        domain.filters.add(f2);
+        domain.queryFilters.add(f1);
+        domain.queryFilters.add(f2);
 
-        SelectQuery query = new SelectQuery(Artist.class);
+        SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
         QueryResponse response = domain.onQuery(context, query);
         assertNotNull(response);
         assertEquals(4, results.size());
@@ -113,55 +94,31 @@ public class DataDomainFiltersIT extends ServerCase {
     public void testOnSync_FilterOrdering() {
 
         DataDomain domain = runtime.getDataDomain();
+        List<String> results = new ArrayList<>();
 
-        final List<String> results = new ArrayList<String>();
-
-        DataChannelFilter f1 = new MockDataChannelFilter() {
-
-            @Override
-            public GraphDiff onSync(
-                    ObjectContext originatingContext,
-                    GraphDiff changes,
-                    int syncType,
-                    DataChannelFilterChain filterChain) {
-
-                results.add("f1start");
-                GraphDiff response = filterChain.onSync(
-                        originatingContext,
-                        changes,
-                        syncType);
-                results.add("f1end");
-                return response;
-            }
+        DataChannelSyncFilter f1 = (originatingContext, changes, syncType, filterChain) -> {
+            results.add("f1start");
+            GraphDiff response = filterChain.onSync(originatingContext, changes, syncType);
+            results.add("f1end");
+            return response;
         };
 
-        DataChannelFilter f2 = new MockDataChannelFilter() {
-
-            @Override
-            public GraphDiff onSync(
-                    ObjectContext originatingContext,
-                    GraphDiff changes,
-                    int syncType,
-                    DataChannelFilterChain filterChain) {
-
-                results.add("f2start");
-                GraphDiff response = filterChain.onSync(
-                        originatingContext,
-                        changes,
-                        syncType);
-                results.add("f2end");
-                return response;
-            }
+        DataChannelSyncFilter f2 = (originatingContext, changes, syncType, filterChain) -> {
+            results.add("f2start");
+            GraphDiff response = filterChain.onSync(originatingContext, changes, syncType);
+            results.add("f2end");
+            return response;
         };
 
-        domain.filters.add(f1);
-        domain.filters.add(f2);
+        domain.syncFilters.add(f1);
+        domain.syncFilters.add(f2);
 
         Artist a = context.newObject(Artist.class);
         a.setArtistName("AAA");
 
         // testing domain.onSync indirectly
         context.commitChanges();
+
         assertEquals(4, results.size());
         assertEquals("f2start", results.get(0));
         assertEquals("f1start", results.get(1));
@@ -174,38 +131,18 @@ public class DataDomainFiltersIT extends ServerCase {
 
         DataDomain domain = runtime.getDataDomain();
 
-        final QueryResponse r1 = new ListResponse();
-        final QueryResponse r2 = new ListResponse();
+        QueryResponse r1 = new ListResponse();
+        QueryResponse r2 = new ListResponse();
 
-        DataChannelFilter f1 = new MockDataChannelFilter() {
+        DataChannelQueryFilter f1 = (originatingContext, query, filterChain) -> r1;
+        DataChannelQueryFilter f2 = (originatingContext, query, filterChain) -> r2;
 
-            @Override
-            public QueryResponse onQuery(
-                    ObjectContext originatingContext,
-                    Query query,
-                    DataChannelFilterChain filterChain) {
+        domain.queryFilters.add(f1);
+        domain.queryFilters.add(f2);
 
-                return r1;
-            }
-        };
-
-        DataChannelFilter f2 = new MockDataChannelFilter() {
-
-            @Override
-            public QueryResponse onQuery(
-                    ObjectContext originatingContext,
-                    Query query,
-                    DataChannelFilterChain filterChain) {
-
-                return r2;
-            }
-        };
-
-        domain.filters.add(f1);
-        domain.filters.add(f2);
-
-        SelectQuery query = new SelectQuery(Artist.class);
+        SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
         QueryResponse response = domain.onQuery(context, query);
+
         assertSame(r2, response);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/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 aa63213..90446c9 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
@@ -177,6 +177,8 @@ 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.contributeDomainQueryFilters(binder);
+            ServerModule.contributeDomainSyncFilters(binder);
             ServerModule.contributeDomainListeners(binder).add(mockListener);
             ServerModule.contributeProjectLocations(binder).add(testConfigName);
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7475b4e0/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
index 14cf472..7969f55 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
@@ -170,6 +170,10 @@ public class ServerCaseModule implements Module {
                 // Should remove problems with random-failing tests (those that are GC-sensitive).
                 .put(Constants.SERVER_OBJECT_RETAIN_STRATEGY_PROPERTY, "soft");
 
+        ServerModule.contributeDomainFilters(binder);
+        ServerModule.contributeDomainSyncFilters(binder);
+        ServerModule.contributeDomainQueryFilters(binder);
+
         binder.bind(PkGeneratorFactoryProvider.class).to(PkGeneratorFactoryProvider.class);
         binder.bind(PkGenerator.class).to(JdbcPkGenerator.class);
         ServerModule.contributePkGenerators(binder)


Mime
View raw message