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/13 13:52:52 UTC

[1/6] cayenne git commit: CAY-1873 | Move DataDomain cache configuration from the Modeler and into DI

Repository: cayenne
Updated Branches:
  refs/heads/master 9c32b7604 -> dfa3d87d8


http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java
new file mode 100644
index 0000000..6e82cd5
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java
@@ -0,0 +1,123 @@
+/*****************************************************************
+ *   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.event;
+
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.configuration.DefaultRuntimeProperties;
+import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.DIBootstrap;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.log.CommonsJdbcEventLogger;
+import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.tx.DefaultTransactionFactory;
+import org.apache.cayenne.tx.DefaultTransactionManager;
+import org.apache.cayenne.tx.TransactionFactory;
+import org.apache.cayenne.tx.TransactionManager;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class JavaGroupsBridgeProviderTest {
+
+    private final DataDomain DOMAIN = new DataDomain("test");
+    private final EventManager EVENT_MANAGER = new DefaultEventManager();
+    protected static final String MCAST_ADDRESS_TEST = "192.168.0.0";
+    protected static final String MCAST_PORT_TEST = "1521";
+    protected static final String CONFIG_URL_TEST = "somehost.com";
+
+    @Test
+    public void testGetJavaGroupsBridge() throws Exception {
+        Module module = new Module() {
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(JavaGroupsBridgeProvider.class);
+                binder.bindMap(Constants.JAVA_GROUPS_BRIDGE_PROPERTIES_MAP);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(module);
+        EventBridge bridge = injector.getInstance(EventBridge.class);
+
+        assertNotNull(bridge);
+        assertTrue(bridge instanceof JavaGroupsBridge);
+    }
+
+    @Test
+    public void testUseProperties() throws Exception {
+        Module module = new Module() {
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(JavaGroupsBridgeProvider.class);
+                binder.bindMap(Constants.JAVA_GROUPS_BRIDGE_PROPERTIES_MAP)
+                        .put(JavaGroupsBridge.MCAST_ADDRESS_PROPERTY, MCAST_ADDRESS_TEST)
+                        .put(JavaGroupsBridge.MCAST_PORT_PROPERTY, MCAST_PORT_TEST)
+                        .put(JavaGroupsBridge.JGROUPS_CONFIG_URL_PROPERTY, CONFIG_URL_TEST);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(module);
+        JavaGroupsBridge bridge = (JavaGroupsBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(MCAST_ADDRESS_TEST, bridge.getMulticastAddress());
+        assertEquals(MCAST_PORT_TEST, bridge.getMulticastPort());
+        assertEquals(CONFIG_URL_TEST, bridge.getConfigURL());
+    }
+
+    @Test
+    public void testUseDefaultProperties() throws Exception {
+        Module module = new Module() {
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(JavaGroupsBridgeProvider.class);
+                binder.bindMap(Constants.JAVA_GROUPS_BRIDGE_PROPERTIES_MAP);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(module);
+        JavaGroupsBridge bridge = (JavaGroupsBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(bridge.getMulticastAddress(), JavaGroupsBridge.MCAST_ADDRESS_DEFAULT);
+        assertEquals(bridge.getMulticastPort(), JavaGroupsBridge.MCAST_PORT_DEFAULT);
+        assertEquals(bridge.getConfigURL(), null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/event/MockEventBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/MockEventBridgeProvider.java b/cayenne-server/src/test/java/org/apache/cayenne/event/MockEventBridgeProvider.java
new file mode 100644
index 0000000..2e99a63
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/event/MockEventBridgeProvider.java
@@ -0,0 +1,43 @@
+/*****************************************************************
+ *   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.event;
+
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.di.DIRuntimeException;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+
+import java.util.Collections;
+
+public class MockEventBridgeProvider implements Provider<EventBridge> {
+
+    @Inject
+    protected DataDomain dataDomain;
+
+    @Override
+    public EventBridge get() throws DIRuntimeException {
+        EventSubject snapshotEventSubject = EventSubject.getSubject(this.getClass(), dataDomain.getName());;
+
+        return new MockEventBridge(
+                Collections.singleton(snapshotEventSubject),
+                EventBridge.convertToExternalSubject(snapshotEventSubject),
+                Collections.EMPTY_MAP);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
index 4eac54a..fb54ede 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
@@ -31,29 +31,42 @@ import static org.junit.Assert.assertTrue;
 
 public class XMPPBridgeFactoryTest {
 
+    protected Collection<EventSubject> subjects = Collections.singleton(new EventSubject("test"));
+    protected String externalSubject = "subject";
+
     @Test
     public void testCreateEventBridge() {
-        XMPPBridgeFactory factory = new XMPPBridgeFactory();
-
-        Collection subjects = Collections.singleton(EventSubject.getSubject(
-                getClass(),
-                "test"));
-        Map properties = new HashMap();
-        properties.put(XMPPBridgeFactory.XMPP_HOST_PROPERTY, "somehost.com");
-        properties.put(XMPPBridgeFactory.XMPP_PORT_PROPERTY, "12345");
-
-        EventBridge bridge = factory.createEventBridge(
+        EventBridge bridge = new XMPPBridgeFactory().createEventBridge(
                 subjects,
-                "remote-subject",
-                properties);
+                externalSubject,
+                Collections.EMPTY_MAP);
 
         assertTrue(bridge instanceof XMPPBridge);
+        assertEquals(subjects, bridge.getLocalSubjects());
+        assertEquals(externalSubject, bridge.getExternalSubject());
+    }
 
-        XMPPBridge xmppBridge = (XMPPBridge) bridge;
+    @Test
+    public void testUseMapPropertiesSetter() throws Exception {
+        XMPPBridgeFactory bridgeFactory = new XMPPBridgeFactory();
+        Map<String, String> properties = new HashMap<String, String>();
+
+        properties.put(XMPPBridge.XMPP_HOST_PROPERTY, XMPPBridgeProviderTest.HOST_TEST);
+        properties.put(XMPPBridge.XMPP_CHAT_SERVICE_PROPERTY, XMPPBridgeProviderTest.CHAT_SERVICE_TEST);
+        properties.put(XMPPBridge.XMPP_LOGIN_PROPERTY, XMPPBridgeProviderTest.LOGIN_TEST);
+        properties.put(XMPPBridge.XMPP_PASSWORD_PROPERTY, XMPPBridgeProviderTest.PASSWORD_TEST);
+        properties.put(XMPPBridge.XMPP_SECURE_CONNECTION_PROPERTY, String.valueOf(XMPPBridgeProviderTest.SECURE_CONNECTION_TEST));
+        properties.put(XMPPBridge.XMPP_PORT_PROPERTY, String.valueOf(XMPPBridgeProviderTest.PORT_TEST));
+
+        XMPPBridge bridge = (XMPPBridge) bridgeFactory.createEventBridge(subjects,
+                externalSubject,
+                properties);
 
-        assertEquals(subjects, xmppBridge.getLocalSubjects());
-        assertEquals("remote-subject", xmppBridge.getExternalSubject());
-        assertEquals("somehost.com", xmppBridge.getXmppHost());
-        assertEquals(12345, xmppBridge.getXmppPort());
+        assertEquals(bridge.getXmppHost(), XMPPBridgeProviderTest.HOST_TEST);
+        assertEquals(bridge.getChatService(), XMPPBridgeProviderTest.CHAT_SERVICE_TEST);
+        assertEquals(bridge.getLoginId(), XMPPBridgeProviderTest.LOGIN_TEST);
+        assertEquals(bridge.getPassword(), XMPPBridgeProviderTest.PASSWORD_TEST);
+        assertEquals(bridge.getXmppPort(), XMPPBridgeProviderTest.PORT_TEST);
+        assertEquals(bridge.isSecureConnection(), XMPPBridgeProviderTest.SECURE_CONNECTION_TEST);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java
new file mode 100644
index 0000000..7d225a5
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java
@@ -0,0 +1,130 @@
+/*****************************************************************
+ *   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.event;
+
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.configuration.DefaultRuntimeProperties;
+import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.DIBootstrap;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.log.CommonsJdbcEventLogger;
+import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.tx.DefaultTransactionFactory;
+import org.apache.cayenne.tx.DefaultTransactionManager;
+import org.apache.cayenne.tx.TransactionFactory;
+import org.apache.cayenne.tx.TransactionManager;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class XMPPBridgeProviderTest {
+
+    private final DataDomain DOMAIN = new DataDomain("test");
+    private final EventManager EVENT_MANAGER = new DefaultEventManager();
+    protected static final String HOST_TEST = "somehost.com";
+    protected static final String CHAT_SERVICE_TEST = "conference";
+    protected static final String LOGIN_TEST = "login";
+    protected static final String PASSWORD_TEST = "password";
+    protected static final boolean SECURE_CONNECTION_TEST = true;
+    protected static final int PORT_TEST = 12345;
+
+    @Test
+    public void testGetXMPPBridge() throws Exception {
+        Module module = new Module() {
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(XMPPBridgeProvider.class);
+                binder.bindMap(Constants.XMPP_BRIDGE_PROPERTIES_MAP);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(module);
+        EventBridge bridge = injector.getInstance(EventBridge.class);
+
+        assertNotNull(bridge);
+        assertTrue(bridge instanceof XMPPBridge);
+    }
+
+    @Test
+    public void testUseProperties() throws Exception {
+        Module module = new Module() {
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(XMPPBridgeProvider.class);
+                binder.bindMap(Constants.XMPP_BRIDGE_PROPERTIES_MAP)
+                        .put(XMPPBridge.XMPP_HOST_PROPERTY, HOST_TEST)
+                        .put(XMPPBridge.XMPP_CHAT_SERVICE_PROPERTY, CHAT_SERVICE_TEST)
+                        .put(XMPPBridge.XMPP_LOGIN_PROPERTY, LOGIN_TEST)
+                        .put(XMPPBridge.XMPP_PASSWORD_PROPERTY, PASSWORD_TEST)
+                        .put(XMPPBridge.XMPP_SECURE_CONNECTION_PROPERTY, String.valueOf(SECURE_CONNECTION_TEST))
+                        .put(XMPPBridge.XMPP_PORT_PROPERTY, String.valueOf(PORT_TEST));
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(module);
+        XMPPBridge bridge = (XMPPBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(HOST_TEST, bridge.getXmppHost());
+        assertEquals(CHAT_SERVICE_TEST, bridge.getChatService());
+        assertEquals(LOGIN_TEST, bridge.getLoginId());
+        assertEquals(PASSWORD_TEST, bridge.getPassword());
+        assertEquals(SECURE_CONNECTION_TEST, bridge.isSecureConnection());
+        assertEquals(PORT_TEST, bridge.getXmppPort());
+    }
+
+    public void testUseDefaultProperties() throws Exception {
+        Module module = new Module() {
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(XMPPBridgeProvider.class);
+                binder.bindMap(Constants.XMPP_BRIDGE_PROPERTIES_MAP);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(module);
+        XMPPBridge bridge = (XMPPBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(bridge.getChatService(), XMPPBridge.DEFAULT_CHAT_SERVICE);
+        assertEquals(bridge.getXmppPort(), XMPPBridge.DEFAULT_XMPP_PORT);
+    }
+}


[3/6] cayenne git commit: CAY-1873 | Remove DataDomain cache configuration from the Modeler

Posted by nt...@apache.org.
CAY-1873 | Remove DataDomain cache configuration from the Modeler


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

Branch: refs/heads/master
Commit: 03136ff1eb6dab04896d7e80dee4d5a56e369042
Parents: a4cba4e
Author: Savva Kolbachev <s....@gmail.com>
Authored: Tue Jun 30 12:05:06 2015 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Mar 10 15:54:44 2017 +0300

----------------------------------------------------------------------
 .../datadomain/CacheSyncConfigController.java   | 337 -------------------
 .../dialog/datadomain/CacheSyncConfigView.java  | 103 ------
 .../CustomRemoteEventsConfigPanel.java          |  58 ----
 .../dialog/datadomain/JGroupsConfigPanel.java   | 104 ------
 .../dialog/datadomain/JMSConfigPanel.java       |  58 ----
 .../cayenne/modeler/editor/DataDomainView.java  | 132 +-------
 6 files changed, 11 insertions(+), 781 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/03136ff1/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigController.java
deleted file mode 100644
index bb43da9..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigController.java
+++ /dev/null
@@ -1,337 +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.modeler.dialog.datadomain;
-
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.swing.WindowConstants;
-
-import org.apache.cayenne.access.DataRowStore;
-import org.apache.cayenne.configuration.DataChannelDescriptor;
-import org.apache.cayenne.configuration.event.DomainEvent;
-import org.apache.cayenne.event.JMSBridgeFactory;
-import org.apache.cayenne.event.JavaGroupsBridgeFactory;
-import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.util.CayenneController;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A controller for CacheSyncConfigDialog and its subviews. This controller 
- * manages one main dialog view, and its subviews organized using CardLayout.
- * 
- */
-public class CacheSyncConfigController extends CayenneController {
-
-    private static Log logObj = LogFactory.getLog(CacheSyncConfigController.class);
-
-    // using strings instead of the actioal factory classes, since we
-    // JMS and JavaGroups libraries may not be around, and Modeler
-    // may throw CNFE
-    private static final String JGROUPS_FACTORY_CLASS = "org.apache.cayenne.event.JavaGroupsBridgeFactory";
-    private static final String JMS_FACTORY_CLASS = "org.apache.cayenne.event.JMSBridgeFactory";
-
-    public static final String SAVE_CONFIG_CONTROL = "Done";
-    public static final String CANCEL_CONFIG_CONTROL = "Cancel";
-
-    public static final String JGROUPS_DEFAULT_CONTROL = "Standard Configuration";
-
-    public static final String JGROUPS_URL_CONTROL = "Use Configuration File";
-    
-    public static final String JGROUPS_FACTORY_LABEL = "JavaGroups Multicast (Default)";
-    public static final String JMS_FACTORY_LABEL = "JMS Transport";
-    public static final String CUSTOM_FACTORY_LABEL = "Custom Transport";
-
-    protected Map existingCards;
-    protected Map properties;
-    protected boolean modified;
-    protected ProjectController eventController;
-    
-    protected CacheSyncConfigView view;
-
-    public CacheSyncConfigController(ProjectController eventController) {
-        super(eventController);
-        this.eventController = eventController;
-    }
-
-    /**
-     * Creates and shows a new modal dialog window.
-     */
-    public void startup() { 
-        DataChannelDescriptor domain = (DataChannelDescriptor)eventController.getProject().getRootNode();
-        
-        String factory = (String) domain.getProperties().get(
-                DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY);
-
-        view = new CacheSyncConfigView();
-        initView();
-        
-        properties = new HashMap(((DataChannelDescriptor)eventController.getProject()
-                .getRootNode()).getProperties());
-        
-        // build cards, showing the one corresponding to DataDomain state
-        prepareChildren(factory);
-        
-        view.pack();
-        view.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
-        view.setModal(true);
-        makeCloseableOnEscape();
-        centerView();
-        view.setVisible(true);
-    }
-    
-    public Component getView() {
-        return this.view;
-    }
-    
-    private void initView() {
-        view.getCancelButton().addActionListener(new ActionListener() {
-            
-            public void actionPerformed(ActionEvent e) {
-                view.dispose();
-            }
-        });
-        view.getSaveButton().addActionListener(new ActionListener() {
-            
-            public void actionPerformed(ActionEvent e) {
-                commitChanges();
-            }
-        });
-        view.getTypeSelector().addActionListener(new ActionListener() {
-            
-            public void actionPerformed(ActionEvent e) {
-                selectCard();
-            }
-        });
-    }
-    
-    protected void selectCard() {
-        view.showCard((String)view.getTypeSelector().getSelectedItem());
-    }
-
-    protected void jgroupsDefaultConfig() {
-        JGroupsConfigPanel view = (JGroupsConfigPanel) existingCards
-                .get(JGROUPS_FACTORY_LABEL);
-        if (view != null) {
-            view.showDefaultConfig();
-        }
-    }
-
-    protected void jgroupsURLConfig() {
-        JGroupsConfigPanel view = (JGroupsConfigPanel) existingCards
-                .get(JGROUPS_FACTORY_LABEL);
-        if (view != null) {
-            view.showCustomConfig();
-        }
-    }
-
-    /**
-     * Stores configuration changes in the data domain properties.
-     */
-    protected void commitChanges() {
-        DataChannelDescriptor domain = (DataChannelDescriptor)eventController.getProject().getRootNode();
-        logObj.warn("domain properties BEFORE: " + domain.getProperties());
-        
-        Map<String, String> props = domain.getProperties();
-        
-        String type = (String)view.getTypeSelector().getSelectedItem();
-        if (JGROUPS_FACTORY_LABEL.equals(type)) {
-            JGroupsConfigPanel jgroupsPanel = (JGroupsConfigPanel) existingCards
-                    .get(JGROUPS_FACTORY_LABEL);
-            props.put(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY, JGROUPS_FACTORY_CLASS);
-            if (jgroupsPanel.useConfigFile.isSelected()) {
-                props.remove(JavaGroupsBridgeFactory.MCAST_ADDRESS_PROPERTY);
-                props.remove(JavaGroupsBridgeFactory.MCAST_PORT_PROPERTY);
-                if (!"".equals(jgroupsPanel.configURL.getText())) {
-                    props.put(JavaGroupsBridgeFactory.JGROUPS_CONFIG_URL_PROPERTY, 
-                            jgroupsPanel.configURL.getText());
-                }
-                else {
-                    props.put(JavaGroupsBridgeFactory.JGROUPS_CONFIG_URL_PROPERTY, null);
-                }
-            }
-            else {
-                props.remove(JavaGroupsBridgeFactory.JGROUPS_CONFIG_URL_PROPERTY);
-                if (!"".equals(jgroupsPanel.multicastAddress.getText())) {
-                    props.put(JavaGroupsBridgeFactory.MCAST_ADDRESS_PROPERTY, 
-                            jgroupsPanel.multicastAddress.getText());
-                }
-                else {
-                    props.put(JavaGroupsBridgeFactory.MCAST_ADDRESS_PROPERTY, null);
-                }
-                if (!"".equals(jgroupsPanel.multicastPort.getText())) { 
-                    props.put(JavaGroupsBridgeFactory.MCAST_PORT_PROPERTY, 
-                            jgroupsPanel.multicastPort.getText());
-                }
-                else {
-                    props.put(JavaGroupsBridgeFactory.MCAST_PORT_PROPERTY, null);
-                }
-            }
-        }
-        else if (JMS_FACTORY_LABEL.equals(type)) {
-            JMSConfigPanel jmsPanel = (JMSConfigPanel) existingCards
-                    .get(JMS_FACTORY_LABEL);
-            props.put(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY, JMS_FACTORY_CLASS);
-            if (!"".equals(jmsPanel.topicFactory.getText())) {
-                props.put(JMSBridgeFactory.TOPIC_CONNECTION_FACTORY_PROPERTY, 
-                        jmsPanel.topicFactory.getText());
-            }
-            else {
-                props.put(JMSBridgeFactory.TOPIC_CONNECTION_FACTORY_PROPERTY, null);
-            }
-        }
-        else if (CUSTOM_FACTORY_LABEL.equals(type)) {
-            CustomRemoteEventsConfigPanel customPanel = (CustomRemoteEventsConfigPanel) existingCards
-                    .get(CUSTOM_FACTORY_LABEL);
-            if (!"".equals(customPanel.factoryClass.getText())) {
-                props.put(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY, customPanel.factoryClass.getText());
-            }
-            else {
-                props.put(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY, null);
-            }
-        }
-        
-        logObj.warn("domain properties: " + domain.getProperties());
-        
-        eventController.fireDomainEvent(new DomainEvent(this, domain));
-
-        view.dispose();
-    }
-    
-    protected void loadProperties(String factory) {
-        String configUrl = (String)properties.get(JavaGroupsBridgeFactory.JGROUPS_CONFIG_URL_PROPERTY);
-        String multicastAddress = (String)properties.get(JavaGroupsBridgeFactory.MCAST_ADDRESS_PROPERTY);
-        String multicastPort = (String)properties.get(JavaGroupsBridgeFactory.MCAST_PORT_PROPERTY);
-        String topicFactory = (String)properties.get(JMSBridgeFactory.TOPIC_CONNECTION_FACTORY_PROPERTY);
-        
-        JGroupsConfigPanel jgroupsPanel = (JGroupsConfigPanel) existingCards
-                .get(JGROUPS_FACTORY_LABEL);
-        
-        if (configUrl != null) {
-            jgroupsPanel.useConfigFile.setSelected(true);
-            jgroupsURLConfig();
-            jgroupsPanel.configURL.setText(configUrl);
-        }
-        else {
-            jgroupsPanel.useDefaultConfig.setSelected(true);
-            jgroupsDefaultConfig();
-        }
-        
-        if (multicastAddress != null) {
-            jgroupsPanel.multicastAddress.setText(multicastAddress);
-        }
-        else {
-            jgroupsPanel.multicastAddress.setText(JavaGroupsBridgeFactory.MCAST_ADDRESS_DEFAULT);
-        }
-        
-        if (multicastPort != null) {
-            jgroupsPanel.multicastPort.setText(multicastPort);
-        }
-        else {
-            jgroupsPanel.multicastPort.setText(JavaGroupsBridgeFactory.MCAST_PORT_DEFAULT);
-        }
-        
-        JMSConfigPanel jmsPanel = (JMSConfigPanel) existingCards
-                .get(JMS_FACTORY_LABEL);
-     
-        if (topicFactory != null) {
-            jmsPanel.topicFactory.setText(topicFactory);
-        }
-        else {
-            jmsPanel.topicFactory.setText(JMSBridgeFactory.TOPIC_CONNECTION_FACTORY_DEFAULT);
-        }
-        
-        CustomRemoteEventsConfigPanel customPanel = (CustomRemoteEventsConfigPanel) existingCards
-                .get(CUSTOM_FACTORY_LABEL);
-        String factoryClass = (String)properties.get(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY);
-        if (factoryClass != null) {
-            customPanel.factoryClass.setText(factoryClass);
-        }
-        else {
-            customPanel.factoryClass.setText(DataRowStore.EVENT_BRIDGE_FACTORY_DEFAULT);
-        }
-        
-        if (JGROUPS_FACTORY_CLASS.equals(factory)) {
-            view.getTypeSelector().setSelectedItem(JGROUPS_FACTORY_LABEL);
-        }
-        else if (JMS_FACTORY_CLASS.equals(factory)) {
-            view.getTypeSelector().setSelectedItem(JMS_FACTORY_LABEL);
-        }
-        else {
-            view.getTypeSelector().setSelectedItem(CUSTOM_FACTORY_LABEL);
-        }
-    }
-
-    protected void prepareChildren(String factory) {
-        existingCards = new HashMap();
-        CacheSyncConfigView topView = (CacheSyncConfigView) getView();
-
-        // note that none of the panels need a controller
-        // if they issue controls, they will use this object taken from parent
-
-        JGroupsConfigPanel jgroupsPanel = new JGroupsConfigPanel();
-        existingCards.put(JGROUPS_FACTORY_LABEL, jgroupsPanel);
-        topView.addCard(jgroupsPanel, JGROUPS_FACTORY_LABEL);
-        
-        jgroupsPanel.getUseDefaultConfig().addActionListener(new ActionListener() {
-            
-            public void actionPerformed(ActionEvent e) {
-                jgroupsDefaultConfig();
-            }
-        });
-        jgroupsPanel.getUseConfigFile().addActionListener(new ActionListener() {
-            
-            public void actionPerformed(ActionEvent e) {
-                jgroupsURLConfig();
-            }
-        });
-
-        JMSConfigPanel jmsPanel = new JMSConfigPanel();
-        existingCards.put(JMS_FACTORY_LABEL, jmsPanel);
-        topView.addCard(jmsPanel, JMS_FACTORY_LABEL);
-
-        CustomRemoteEventsConfigPanel customFactoryPanel = new CustomRemoteEventsConfigPanel();
-        existingCards.put(CUSTOM_FACTORY_LABEL, customFactoryPanel);
-        topView.addCard(customFactoryPanel, CUSTOM_FACTORY_LABEL);
-
-        if (factory == null) {
-            factory = DataRowStore.EVENT_BRIDGE_FACTORY_DEFAULT;
-        }
-
-        if (JGROUPS_FACTORY_CLASS.equals(factory)) {
-            ((CacheSyncConfigView) getView())
-                    .showCard(JGROUPS_FACTORY_LABEL);
-        }
-        else if (JMS_FACTORY_CLASS.equals(factory)) {
-            ((CacheSyncConfigView) getView())
-                    .showCard(JMS_FACTORY_LABEL);
-        }
-        else {
-            ((CacheSyncConfigView) getView())
-                    .showCard(CUSTOM_FACTORY_LABEL);
-        }
-        
-        loadProperties(factory);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/03136ff1/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigView.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigView.java
deleted file mode 100644
index a9f0d51..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigView.java
+++ /dev/null
@@ -1,103 +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.modeler.dialog.datadomain;
-
-import java.awt.BorderLayout;
-import java.awt.CardLayout;
-import java.awt.Component;
-import java.awt.FlowLayout;
-
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JDialog;
-import javax.swing.JPanel;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-/**
- */
-public class CacheSyncConfigView extends JDialog {
-    public static final String EMPTY_CARD_KEY = "Empty";
-
-    protected JPanel configPanel;
-    protected JComboBox typeSelector;
-    protected JButton saveButton;
-    protected JButton cancelButton;
-
-    public CacheSyncConfigView() {
-        initView();
-    }
-
-    protected void initView() {
-        this.setLayout(new BorderLayout());
-        this.setTitle("Configure Remote Cache Synchronization");
-
-        typeSelector = new JComboBox();
-        typeSelector.addItem("JavaGroups Multicast (Default)");
-        typeSelector.addItem("JMS Transport");
-        typeSelector.addItem("Custom Transport");
-
-        saveButton = new JButton(CacheSyncConfigController.SAVE_CONFIG_CONTROL);
-        cancelButton =
-            new JButton(CacheSyncConfigController.CANCEL_CONFIG_CONTROL);
-
-        // buttons panel
-        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
-        buttonPanel.add(saveButton);
-        buttonPanel.add(cancelButton);
-
-        // type form
-        FormLayout layout = new FormLayout("right:150, 3dlu, left:200", "");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-        builder.append("Notification Transport Type:", typeSelector);
-
-        // config panel
-        configPanel = new JPanel(new CardLayout());
-        addCard(new JPanel(), EMPTY_CARD_KEY);
-
-        this.add(builder.getPanel(), BorderLayout.NORTH);
-        this.add(configPanel, BorderLayout.CENTER);
-        this.add(buttonPanel, BorderLayout.SOUTH);
-
-        showCard(EMPTY_CARD_KEY);
-    }
-
-    public void addCard(Component card, String key) {
-        configPanel.add(card, key);
-    }
-
-    public void showCard(String key) {
-        ((CardLayout) configPanel.getLayout()).show(configPanel, key);
-    }
-
-    public JButton getSaveButton() {
-        return this.saveButton;
-    }
-
-    public JButton getCancelButton() {
-        return this.cancelButton;
-    }
-
-    public JComboBox getTypeSelector() {
-        return this.typeSelector;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/03136ff1/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CustomRemoteEventsConfigPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CustomRemoteEventsConfigPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CustomRemoteEventsConfigPanel.java
deleted file mode 100644
index 82bcc4c..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CustomRemoteEventsConfigPanel.java
+++ /dev/null
@@ -1,58 +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.modeler.dialog.datadomain;
-
-import java.awt.BorderLayout;
-
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-/**
- */
-public class CustomRemoteEventsConfigPanel extends JPanel {
-    
-    protected JTextField factoryClass;
-    
-    public CustomRemoteEventsConfigPanel() {
-        super();
-        initView();
-    }
-
-    protected void initView() {
-        setLayout(new BorderLayout());
-
-        factoryClass = new JTextField(30);
-
-        // type form
-        FormLayout layout = new FormLayout("right:150, 3dlu, left:200", "");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-        builder.appendSeparator("Custom EventBridge Factory");
-
-        // "1" at the end would enforce spanning the text field to
-        // the full width
-        builder.append("Factory Class:", factoryClass, 1);
-
-        add(builder.getPanel(), BorderLayout.NORTH);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/03136ff1/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JGroupsConfigPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JGroupsConfigPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JGroupsConfigPanel.java
deleted file mode 100644
index 0d38ef6..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JGroupsConfigPanel.java
+++ /dev/null
@@ -1,104 +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.modeler.dialog.datadomain;
-
-import java.awt.BorderLayout;
-
-import javax.swing.ButtonGroup;
-import javax.swing.JPanel;
-import javax.swing.JRadioButton;
-import javax.swing.JTextField;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-public class JGroupsConfigPanel extends JPanel {
-
-    protected JTextField multicastAddress;
-    protected JTextField multicastPort;
-    protected JTextField configURL;
-    protected JRadioButton useDefaultConfig;
-    protected JRadioButton useConfigFile;
-    
-    public JGroupsConfigPanel() {
-        initView();
-    }
-
-    protected void initView() {
-        setLayout(new BorderLayout());
-
-        useDefaultConfig = new JRadioButton(CacheSyncConfigController.JGROUPS_DEFAULT_CONTROL);
-        useDefaultConfig.setSelected(true);
-        useConfigFile = new JRadioButton(CacheSyncConfigController.JGROUPS_URL_CONTROL);
-        
-        ButtonGroup radioGroup = new ButtonGroup();
-        radioGroup.add(useConfigFile);
-        radioGroup.add(useDefaultConfig);
-
-        multicastAddress = new JTextField(20);
-        multicastPort = new JTextField(5);
-        configURL = new JTextField(20);
-
-        // type form
-        FormLayout layout = new FormLayout("right:150, 3dlu, left:200", "");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-        builder.appendSeparator("JavaGroups Settings");
-
-        builder.append(useDefaultConfig);
-        builder.nextLine();
-
-        // "1" at the end would enforce spanning the text field to
-        // the full width
-        builder.append("Multicast Address:", multicastAddress, 1);
-        builder.append("Multicast Port:", multicastPort);
-
-        builder.nextLine();
-        builder.append(useConfigFile);
-        builder.nextLine();
-        builder.append("JGroups Config File:", configURL, 1);
-
-        add(builder.getPanel(), BorderLayout.NORTH);
-    }
-
-    public void showDefaultConfig() {
-        multicastAddress.setEditable(true);
-        multicastPort.setEditable(true);
-        configURL.setEditable(false);
-    }
-
-    public void showCustomConfig() {
-        multicastAddress.setEditable(false);
-        multicastPort.setEditable(false);
-        configURL.setEditable(true);
-    }
-    
-    public JRadioButton getUseDefaultConfig() {
-        return this.useDefaultConfig;
-    }
-    
-    public void setUseDefaultConfig(JRadioButton button) {
-        this.useDefaultConfig = button;
-    }
-    
-    public JRadioButton getUseConfigFile() {
-        return this.useConfigFile;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/03136ff1/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JMSConfigPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JMSConfigPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JMSConfigPanel.java
deleted file mode 100644
index e896b53..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JMSConfigPanel.java
+++ /dev/null
@@ -1,58 +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.modeler.dialog.datadomain;
-
-import java.awt.BorderLayout;
-
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-/**
- */
-public class JMSConfigPanel extends JPanel {
-    
-    protected JTextField topicFactory;
-
-    public JMSConfigPanel() {
-        super();
-        initView();
-    }
-
-    protected void initView() {
-        setLayout(new BorderLayout());
-
-        topicFactory = new JTextField(30);
-
-        // type form
-        FormLayout layout = new FormLayout("right:150, 3dlu, left:200", "");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-        builder.appendSeparator("JMS Settings");
-
-        // "1" at the end would enforce spanning the text field to
-        // the full width
-        builder.append("Connection Factory Name:", topicFactory, 1);
-
-        add(builder.getPanel(), BorderLayout.NORTH);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/03136ff1/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java
index ebc5473..7f225c8 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java
@@ -19,24 +19,14 @@
 
 package org.apache.cayenne.modeler.editor;
 
-import java.awt.BorderLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.Map;
-import java.util.prefs.Preferences;
-
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
+import com.jgoodies.forms.builder.PanelBuilder;
+import com.jgoodies.forms.layout.CellConstraints;
+import com.jgoodies.forms.layout.FormLayout;
 import org.apache.cayenne.access.DataDomain;
-import org.apache.cayenne.access.DataRowStore;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.configuration.event.DomainEvent;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.dialog.datadomain.CacheSyncConfigController;
 import org.apache.cayenne.modeler.event.DomainDisplayEvent;
 import org.apache.cayenne.modeler.event.DomainDisplayListener;
 import org.apache.cayenne.modeler.util.TextAdapter;
@@ -44,9 +34,14 @@ import org.apache.cayenne.pref.RenamedPreferences;
 import org.apache.cayenne.util.Util;
 import org.apache.cayenne.validation.ValidationException;
 
-import com.jgoodies.forms.builder.PanelBuilder;
-import com.jgoodies.forms.layout.CellConstraints;
-import com.jgoodies.forms.layout.FormLayout;
+import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Map;
+import java.util.prefs.Preferences;
 
 /**
  * Panel for editing DataDomain.
@@ -56,11 +51,7 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
     protected ProjectController projectController;
 
     protected TextAdapter name;
-    protected TextAdapter cacheSize;
     protected JCheckBox objectValidation;
-    protected JCheckBox sharedCache;
-    protected JCheckBox remoteUpdates;
-    protected JButton configRemoteUpdates;
 
     public DataDomainView(ProjectController projectController) {
         this.projectController = projectController;
@@ -82,18 +73,7 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
             }
         };
 
-        this.cacheSize = new TextAdapter(new JTextField(10)) {
-
-            protected void updateModel(String text) {
-                setCacheSize(text);
-            }
-        };
-
         this.objectValidation = new JCheckBox();
-        this.sharedCache = new JCheckBox();
-        this.remoteUpdates = new JCheckBox();
-        this.configRemoteUpdates = new JButton("Configure...");
-        configRemoteUpdates.setEnabled(false);
 
         // assemble
         CellConstraints cc = new CellConstraints();
@@ -111,18 +91,6 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
         builder.addLabel("Object Validation:", cc.xy(1, 5));
         builder.add(objectValidation, cc.xy(3, 5));
 
-        builder.addSeparator("Cache Configuration", cc.xywh(1, 7, 7, 1));
-
-        builder.addLabel("Size of Object Cache:", cc.xy(1, 9));
-        builder.add(cacheSize.getComponent(), cc.xy(3, 9));
-
-        builder.addLabel("Use Shared Cache:", cc.xy(1, 11));
-        builder.add(sharedCache, cc.xy(3, 11));
-
-        builder.addLabel("Remote Change Notifications:", cc.xy(1, 13));
-        builder.add(remoteUpdates, cc.xy(3, 13));
-        builder.add(configRemoteUpdates, cc.xy(7, 13));
-
         this.setLayout(new BorderLayout());
         this.add(builder.getPanel(), BorderLayout.CENTER);
     }
@@ -142,55 +110,6 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
             }
         });
 
-        sharedCache.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                String value = sharedCache.isSelected() ? "true" : "false";
-                setDomainProperty(
-                        DataDomain.SHARED_CACHE_ENABLED_PROPERTY,
-                        value,
-                        Boolean.toString(DataDomain.SHARED_CACHE_ENABLED_DEFAULT));
-
-                // turning off shared cache should result in disabling remote events
-
-                remoteUpdates.setEnabled(sharedCache.isSelected());
-
-                if (!sharedCache.isSelected()) {
-                    // uncheck remote updates...
-                    remoteUpdates.setSelected(false);
-
-                    setDomainProperty(
-                            DataRowStore.REMOTE_NOTIFICATION_PROPERTY,
-                            "false",
-                            Boolean.toString(DataRowStore.REMOTE_NOTIFICATION_DEFAULT));
-                }
-
-                // depending on final remote updates status change button status
-                configRemoteUpdates.setEnabled(remoteUpdates.isSelected());
-            }
-        });
-
-        remoteUpdates.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                String value = remoteUpdates.isSelected() ? "true" : "false";
-
-                // update config button state
-                configRemoteUpdates.setEnabled(remoteUpdates.isSelected());
-
-                setDomainProperty(
-                        DataRowStore.REMOTE_NOTIFICATION_PROPERTY,
-                        value,
-                        Boolean.toString(DataRowStore.REMOTE_NOTIFICATION_DEFAULT));
-            }
-        });
-
-        configRemoteUpdates.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                new CacheSyncConfigController(projectController).startup();
-            }
-        });
     }
 
     /**
@@ -258,24 +177,9 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
         // extract values from the new domain object
         name.setText(domain.getName());
 
-        cacheSize.setText(getDomainProperty(
-                DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY,
-                Integer.toString(DataRowStore.SNAPSHOT_CACHE_SIZE_DEFAULT)));
-
         objectValidation.setSelected(getDomainBooleanProperty(
                 DataDomain.VALIDATING_OBJECTS_ON_COMMIT_PROPERTY,
                 Boolean.toString(DataDomain.VALIDATING_OBJECTS_ON_COMMIT_DEFAULT)));
-
-        sharedCache.setSelected(getDomainBooleanProperty(
-                DataDomain.SHARED_CACHE_ENABLED_PROPERTY,
-                Boolean.toString(DataDomain.SHARED_CACHE_ENABLED_DEFAULT)));
-
-        remoteUpdates.setSelected(getDomainBooleanProperty(
-                DataRowStore.REMOTE_NOTIFICATION_PROPERTY,
-                Boolean.toString(DataRowStore.REMOTE_NOTIFICATION_DEFAULT)));
-        remoteUpdates.setEnabled(sharedCache.isSelected());
-        configRemoteUpdates.setEnabled(remoteUpdates.isEnabled()
-                && remoteUpdates.isSelected());
     }
 
     void setDomainName(String newName) {
@@ -304,18 +208,4 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
         RenamedPreferences.copyPreferences(newName, prefs);
         projectController.fireDomainEvent(e);
     }
-
-    void setCacheSize(String text) {
-        if (text.length() > 0) {
-            try {
-                Integer.parseInt(text);
-            }
-            catch (NumberFormatException ex) {
-                throw new ValidationException("Cache size must be an integer: " + text);
-            }
-        }
-
-        setDomainProperty(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, text, Integer
-                .toString(DataRowStore.SNAPSHOT_CACHE_SIZE_DEFAULT));
-    }
 }


[4/6] cayenne git commit: CAY-1873 | Add DataDomain cache configuration into DI

Posted by nt...@apache.org.
CAY-1873 | Add DataDomain cache configuration into DI


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

Branch: refs/heads/master
Commit: a4cba4e0c12e7f77de6b3454e3940444cdd1f64f
Parents: 9c32b76
Author: Savva Kolbachev <s....@gmail.com>
Authored: Mon Jun 29 11:11:41 2015 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Mar 10 15:54:44 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/access/DataDomain.java   |  48 ++++----
 .../cayenne/access/DataRowStoreFactory.java     |  38 ++++++
 .../access/DefaultDataRowStoreFactory.java      |  47 ++++++++
 .../apache/cayenne/configuration/Constants.java |   8 ++
 .../server/DataContextFactory.java              |  18 ++-
 .../configuration/server/ServerModule.java      |  33 ++++-
 .../cayenne/access/DataRowStoreFactoryIT.java   | 119 +++++++++++++++++++
 .../server/DataContextFactoryTest.java          |   7 ++
 8 files changed, 283 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/a4cba4e0/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 9bc0129..73e0c02 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
@@ -92,6 +92,12 @@ public class DataDomain implements QueryEngine, DataChannel {
 	protected TransactionManager transactionManager;
 
 	/**
+     * @since 4.0
+     */
+    @Inject
+    protected DataRowStoreFactory dataRowStoreFactory;
+
+    /**
 	 * @since 3.1
 	 */
 	protected int maxIdQualifierSize;
@@ -137,7 +143,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	/**
 	 * Creates new DataDomain.
-	 * 
+	 *
 	 * @param name
 	 *            DataDomain name. Domain can be located using its name in the
 	 *            Configuration object.
@@ -168,7 +174,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	/**
 	 * Checks that Domain is not stopped. Throws DomainStoppedException
 	 * otherwise.
-	 * 
+	 *
 	 * @since 3.0
 	 */
 	protected void checkStopped() throws DomainStoppedException {
@@ -204,7 +210,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	/**
 	 * Reinitializes domain state with a new set of properties.
-	 * 
+	 *
 	 * @since 1.1
 	 * @deprecated since 4.0 properties are processed by the DI provider.
 	 */
@@ -228,7 +234,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	/**
 	 * Returns EventManager used by this DataDomain.
-	 * 
+	 *
 	 * @since 1.2
 	 */
 	public EventManager getEventManager() {
@@ -237,7 +243,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	/**
 	 * Sets EventManager used by this DataDomain.
-	 * 
+	 *
 	 * @since 1.2
 	 */
 	public void setEventManager(EventManager eventManager) {
@@ -282,7 +288,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	/**
 	 * Returns whether child DataContexts default behavior is to perform object
 	 * validation before commit is executed.
-	 * 
+	 *
 	 * @since 1.1
 	 */
 	public boolean isValidatingObjectsOnCommit() {
@@ -292,7 +298,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	/**
 	 * Sets the property defining whether child DataContexts should perform
 	 * object validation before commit is executed.
-	 * 
+	 *
 	 * @since 1.1
 	 */
 	public void setValidatingObjectsOnCommit(boolean flag) {
@@ -325,7 +331,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	 */
 	synchronized DataRowStore nonNullSharedSnapshotCache() {
 		if (sharedSnapshotCache == null) {
-			this.sharedSnapshotCache = new DataRowStore(name, properties, eventManager);
+			this.sharedSnapshotCache = dataRowStoreFactory.createDataRowStore(name);
 		}
 
 		return sharedSnapshotCache;
@@ -365,7 +371,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	/**
 	 * Removes named DataMap from this DataDomain and any underlying DataNodes
 	 * that include it.
-	 * 
+	 *
 	 * @since 3.1
 	 */
 	public void removeDataMap(String mapName) {
@@ -441,7 +447,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	/**
 	 * Returns registered DataNode whose name matches <code>name</code>
 	 * parameter.
-	 * 
+	 *
 	 * @since 3.1
 	 */
 	public DataNode getDataNode(String nodeName) {
@@ -451,7 +457,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	/**
 	 * Returns a DataNode that should handle queries for all entities in a
 	 * DataMap.
-	 * 
+	 *
 	 * @since 1.1
 	 */
 	public DataNode lookupDataNode(DataMap map) {
@@ -493,7 +499,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	/**
 	 * Sets EntityResolver. If not set explicitly, DataDomain creates a default
 	 * EntityResolver internally on demand.
-	 * 
+	 *
 	 * @since 1.1
 	 */
 	public void setEntityResolver(EntityResolver entityResolver) {
@@ -541,7 +547,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	/**
 	 * Runs query returning generic QueryResponse.
-	 * 
+	 *
 	 * @since 1.2
 	 */
 	@Override
@@ -574,7 +580,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	/**
 	 * Only handles commit-type synchronization, ignoring any other type.
-	 * 
+	 *
 	 * @since 1.2
 	 */
 	@Override
@@ -636,7 +642,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	/**
 	 * Returns shared {@link QueryCache} used by this DataDomain.
-	 * 
+	 *
 	 * @since 3.0
 	 */
 	public QueryCache getQueryCache() {
@@ -666,7 +672,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	 * 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
 	 */
 	public List<DataChannelFilter> getFilters() {
@@ -677,7 +683,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	 * Adds a new filter, immediately calling its 'init' method. Since 4.0 this
 	 * method also registers passed filter as an event listener, if any of its
 	 * methods have event annotations.
-	 * 
+	 *
 	 * @since 3.1
 	 */
 	public void addFilter(DataChannelFilter filter) {
@@ -688,7 +694,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 
 	/**
 	 * Removes a filter from the filter chain.
-	 * 
+	 *
 	 * @since 3.1
 	 */
 	public void removeFilter(DataChannelFilter filter) {
@@ -699,7 +705,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	 * Adds a listener, mapping its methods to events based on annotations. This
 	 * is a shortcut for
 	 * 'getEntityResolver().getCallbackRegistry().addListener(listener)'.
-	 * 
+	 *
 	 * @since 4.0
 	 */
 	public void addListener(Object listener) {
@@ -756,7 +762,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	/**
 	 * An optional DataNode that is used for DataMaps that are not linked to a
 	 * DataNode explicitly.
-	 * 
+	 *
 	 * @since 3.1
 	 */
 	public DataNode getDefaultNode() {
@@ -780,7 +786,7 @@ public class DataDomain implements QueryEngine, DataChannel {
 	 * changed either by calling {@link #setMaxIdQualifierSize(int)} or changing
 	 * the value for property
 	 * {@link Constants#SERVER_MAX_ID_QUALIFIER_SIZE_PROPERTY}.
-	 * 
+	 *
 	 * @since 3.1
 	 */
 	public int getMaxIdQualifierSize() {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a4cba4e0/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStoreFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStoreFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStoreFactory.java
new file mode 100644
index 0000000..7939468
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStoreFactory.java
@@ -0,0 +1,38 @@
+/*****************************************************************
+ *   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.access;
+
+/**
+ * A factory for creating {@link DataRowStore}
+ *
+ * @since 4.0
+ */
+public interface DataRowStoreFactory {
+
+    /**
+     * Create new {@link DataRowStore} object.
+     *
+     * @since 4.0
+     * @param name DataRowStore name. Used to identify this DataRowStore in events, etc.
+     *             Can't be null.
+     */
+    DataRowStore createDataRowStore(String name);
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a4cba4e0/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
new file mode 100644
index 0000000..f6f67fc
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
@@ -0,0 +1,47 @@
+/*****************************************************************
+ *   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.access;
+
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.di.DIRuntimeException;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.event.EventManager;
+
+import java.util.Map;
+
+/**
+ * A default implementation of {@link DataRowStoreFactory}
+ *
+ * @since 4.0
+ */
+public class DefaultDataRowStoreFactory implements DataRowStoreFactory {
+
+    @Inject
+    protected EventManager eventManager;
+
+    @Inject(Constants.DATA_ROW_STORE_PROPERTIES_MAP)
+    Map<String, String> properties;
+
+    @Override
+    public DataRowStore createDataRowStore(String name) throws DIRuntimeException {
+        return new DataRowStore(name, properties, eventManager);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a4cba4e0/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 7844d6e..18c42cd 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
@@ -264,4 +264,12 @@ public interface Constants {
     @Deprecated
     public static final String ROP_CONTEXT_LIFECYCLE_EVENTS_PROPERTY = "cayenne.rop.context_lifecycle_events";
 
+    /**
+     * A DI container key for the Map&lt;String, String&gt; storing
+     * {@link org.apache.cayenne.access.DataRowStore} properties
+     *
+     * @since 4.0
+     */
+    public static final String DATA_ROW_STORE_PROPERTIES_MAP = "cayenne.server.data_row_store";
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a4cba4e0/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataContextFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataContextFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataContextFactory.java
index b6b51a1..f5cca8b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataContextFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataContextFactory.java
@@ -23,13 +23,13 @@ import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataRowStore;
+import org.apache.cayenne.access.DataRowStoreFactory;
 import org.apache.cayenne.access.ObjectStore;
 import org.apache.cayenne.cache.NestedQueryCache;
 import org.apache.cayenne.cache.QueryCache;
 import org.apache.cayenne.configuration.ObjectContextFactory;
 import org.apache.cayenne.configuration.ObjectStoreFactory;
 import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.tx.TransactionFactory;
 
@@ -45,7 +45,7 @@ public class DataContextFactory implements ObjectContextFactory {
     protected EventManager eventManager;
 
     @Inject
-    protected Injector injector;
+    protected DataRowStoreFactory dataRowStoreFactory;
     
     @Inject
     protected ObjectStoreFactory objectStoreFactory;
@@ -80,11 +80,9 @@ public class DataContextFactory implements ObjectContextFactory {
 
         // for new dataRowStores use the same name for all stores
         // it makes it easier to track the event subject
-        DataRowStore snapshotCache = (dataDomain.isSharedCacheEnabled()) ? dataDomain
-                .getSharedSnapshotCache() : new DataRowStore(
-                dataDomain.getName(),
-                dataDomain.getProperties(),
-                eventManager);
+        DataRowStore snapshotCache = (dataDomain.isSharedCacheEnabled())
+                ? dataDomain.getSharedSnapshotCache()
+                : dataRowStoreFactory.createDataRowStore(dataDomain.getName());
 
         DataContext context = newInstance(
                 parent, objectStoreFactory.createObjectStore(snapshotCache));
@@ -112,9 +110,9 @@ public class DataContextFactory implements ObjectContextFactory {
 
         // for new dataRowStores use the same name for all stores
         // it makes it easier to track the event subject
-        DataRowStore snapshotCache = (parent.isSharedCacheEnabled()) ? parent
-                .getSharedSnapshotCache() : new DataRowStore(parent.getName(), parent
-                .getProperties(), eventManager);
+        DataRowStore snapshotCache = (parent.isSharedCacheEnabled())
+                ? parent.getSharedSnapshotCache()
+                : dataRowStoreFactory.createDataRowStore(parent.getName());
 
         DataContext context = newInstance(
                 parent, objectStoreFactory.createObjectStore(snapshotCache));

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a4cba4e0/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 e8314c0..2f8590d 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
@@ -21,6 +21,8 @@ package org.apache.cayenne.configuration.server;
 import org.apache.cayenne.DataChannel;
 import org.apache.cayenne.DataChannelFilter;
 import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.access.DataRowStoreFactory;
+import org.apache.cayenne.access.DefaultDataRowStoreFactory;
 import org.apache.cayenne.access.DefaultObjectMapRetainStrategy;
 import org.apache.cayenne.access.ObjectMapRetainStrategy;
 import org.apache.cayenne.access.dbsync.DefaultSchemaUpdateStrategyFactory;
@@ -32,7 +34,24 @@ 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.access.types.*;
+import org.apache.cayenne.access.types.BigDecimalType;
+import org.apache.cayenne.access.types.BigIntegerType;
+import org.apache.cayenne.access.types.BooleanType;
+import org.apache.cayenne.access.types.ByteArrayType;
+import org.apache.cayenne.access.types.ByteType;
+import org.apache.cayenne.access.types.CalendarType;
+import org.apache.cayenne.access.types.CharType;
+import org.apache.cayenne.access.types.DateType;
+import org.apache.cayenne.access.types.DoubleType;
+import org.apache.cayenne.access.types.FloatType;
+import org.apache.cayenne.access.types.IntegerType;
+import org.apache.cayenne.access.types.LongType;
+import org.apache.cayenne.access.types.ShortType;
+import org.apache.cayenne.access.types.TimeType;
+import org.apache.cayenne.access.types.TimestampType;
+import org.apache.cayenne.access.types.UUIDType;
+import org.apache.cayenne.access.types.UtilDateType;
+import org.apache.cayenne.access.types.VoidType;
 import org.apache.cayenne.ashwood.AshwoodEntitySorter;
 import org.apache.cayenne.cache.MapQueryCacheProvider;
 import org.apache.cayenne.cache.QueryCache;
@@ -64,7 +83,12 @@ import org.apache.cayenne.dba.postgres.PostgresSniffer;
 import org.apache.cayenne.dba.sqlite.SQLiteSniffer;
 import org.apache.cayenne.dba.sqlserver.SQLServerSniffer;
 import org.apache.cayenne.dba.sybase.SybaseSniffer;
-import org.apache.cayenne.di.*;
+import org.apache.cayenne.di.AdhocObjectFactory;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.ClassLoaderManager;
+import org.apache.cayenne.di.Key;
+import org.apache.cayenne.di.ListBuilder;
+import org.apache.cayenne.di.Module;
 import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
 import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
 import org.apache.cayenne.event.DefaultEventManager;
@@ -268,8 +292,9 @@ public class ServerModule implements Module {
 
         binder.bind(QueryCache.class).toProvider(MapQueryCacheProvider.class);
 
-        // a service to provide the main stack DataDomain
-        binder.bind(DataDomain.class).toProvider(DataDomainProvider.class);
+		binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+        binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);// a service to provide the main stack DataDomain
+		binder.bind(DataDomain.class).toProvider(DataDomainProvider.class);
 
         binder.bind(DataNodeFactory.class).to(DefaultDataNodeFactory.class);
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a4cba4e0/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java
new file mode 100644
index 0000000..743368c
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java
@@ -0,0 +1,119 @@
+/*****************************************************************
+ *   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.access;
+
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.configuration.DefaultRuntimeProperties;
+import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.DIBootstrap;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.event.DefaultEventManager;
+import org.apache.cayenne.event.EventManager;
+import org.apache.cayenne.log.CommonsJdbcEventLogger;
+import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.tx.DefaultTransactionFactory;
+import org.apache.cayenne.tx.DefaultTransactionManager;
+import org.apache.cayenne.tx.TransactionFactory;
+import org.apache.cayenne.tx.TransactionManager;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@UseServerRuntime(CayenneProjects.MULTI_TIER_PROJECT)
+public class DataRowStoreFactoryIT extends ServerCase {
+
+    @Test
+    public void testGetDataRowStore() throws Exception {
+        ServerRuntime runtime = getUnitTestInjector().getInstance(ServerRuntime.class);
+        DataRowStore dataStore = runtime.getInjector().getInstance(DataRowStoreFactory.class)
+                .createDataRowStore("test");
+
+        assertNotNull(dataStore);
+    }
+
+    @Test
+    public void testGetDataRowStoreWithParameters() {
+        final DataDomain DOMAIN = new DataDomain("test");
+        final EventManager EVENT_MANAGER = new DefaultEventManager();
+        final int CACHE_SIZE = 500;
+        final int EXPIRATION_PROPERTY = 60 * 60 * 24;
+
+        Module testModule = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+                binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP)
+                        .put(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, String.valueOf(CACHE_SIZE))
+                        .put(DataRowStore.SNAPSHOT_EXPIRATION_PROPERTY, String.valueOf(EXPIRATION_PROPERTY));
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(testModule);
+        DataRowStore dataStore = injector.getInstance(DataRowStoreFactory.class)
+                .createDataRowStore("test");
+
+        assertNotNull(dataStore);
+        assertEquals(dataStore.maximumSize(), CACHE_SIZE);
+    }
+
+    @Test
+    public void testGetDataRowStoreWithBridge() {
+        final DataDomain DOMAIN = new DataDomain("test");
+        final EventManager EVENT_MANAGER = new DefaultEventManager();
+
+        Module testModule = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+                binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(testModule);
+        DataRowStore dataStore = injector.getInstance(DataRowStoreFactory.class)
+                .createDataRowStore("test");
+
+        dataStore.stopListeners();
+        dataStore.startListeners();
+        dataStore.shutdown();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a4cba4e0/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
index cdb7e6b..0304a2e 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
@@ -20,10 +20,13 @@ package org.apache.cayenne.configuration.server;
 
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.access.DataRowStoreFactory;
+import org.apache.cayenne.access.DefaultDataRowStoreFactory;
 import org.apache.cayenne.access.DefaultObjectMapRetainStrategy;
 import org.apache.cayenne.access.ObjectMapRetainStrategy;
 import org.apache.cayenne.cache.MapQueryCache;
 import org.apache.cayenne.cache.QueryCache;
+import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.DefaultObjectStoreFactory;
 import org.apache.cayenne.configuration.DefaultRuntimeProperties;
 import org.apache.cayenne.configuration.ObjectStoreFactory;
@@ -74,6 +77,8 @@ public class DataContextFactoryTest {
                 binder.bind(ObjectStoreFactory.class).to(DefaultObjectStoreFactory.class);
                 binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
                 binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+                binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
             }
         };
 
@@ -111,6 +116,8 @@ public class DataContextFactoryTest {
                 binder.bind(ObjectStoreFactory.class).to(DefaultObjectStoreFactory.class);
                 binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
                 binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+                binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
             }
         };
 


[2/6] cayenne git commit: CAY-1873 | Move DataDomain cache configuration from the Modeler and into DI

Posted by nt...@apache.org.
CAY-1873 | Move DataDomain cache configuration from the Modeler and into DI


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

Branch: refs/heads/master
Commit: dae15ceeea25a70fddeb20ad1bad83022cabf07d
Parents: 03136ff
Author: Savva Kolbachev <s....@gmail.com>
Authored: Thu Jul 2 18:32:01 2015 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Mar 10 15:54:44 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/access/DataRowStore.java | 120 ++++++++---------
 .../access/DefaultDataRowStoreFactory.java      |  20 ++-
 .../apache/cayenne/configuration/Constants.java |  24 ++++
 .../server/DataDomainProvider.java              |   2 +
 .../configuration/server/ServerModule.java      |   8 +-
 .../cayenne/event/EventBridgeFactory.java       |   2 +-
 .../cayenne/event/EventBridgeProvider.java      |  60 +++++++++
 .../org/apache/cayenne/event/JMSBridge.java     |  35 ++++-
 .../apache/cayenne/event/JMSBridgeFactory.java  |  19 +--
 .../apache/cayenne/event/JMSBridgeProvider.java |  50 +++++++
 .../apache/cayenne/event/JavaGroupsBridge.java  |  33 ++++-
 .../cayenne/event/JavaGroupsBridgeFactory.java  | 109 +---------------
 .../cayenne/event/JavaGroupsBridgeProvider.java |  50 +++++++
 .../org/apache/cayenne/event/XMPPBridge.java    |  62 +++++++--
 .../apache/cayenne/event/XMPPBridgeFactory.java |  53 +-------
 .../cayenne/event/XMPPBridgeProvider.java       |  50 +++++++
 .../cayenne/access/DataRowStoreFactoryIT.java   | 119 -----------------
 .../apache/cayenne/access/DataRowStoreIT.java   |  32 -----
 .../access/DefaultDataRowStoreFactoryIT.java    | 123 ++++++++++++++++++
 .../apache/cayenne/access/MockDataRowStore.java |   7 +-
 .../server/DataContextFactoryTest.java          |   7 +
 .../server/DataDomainProviderTest.java          |   8 ++
 .../cayenne/event/JGroupsBridgeFactoryTest.java |  46 -------
 .../cayenne/event/JMSBridgeFactoryTest.java     |  77 +++++++++++
 .../cayenne/event/JMSBridgeProviderTest.java    | 119 +++++++++++++++++
 .../event/JavaGroupsBridgeFactoryTest.java      |  84 ++++++++++++
 .../event/JavaGroupsBridgeProviderTest.java     | 123 ++++++++++++++++++
 .../cayenne/event/MockEventBridgeProvider.java  |  43 ++++++
 .../cayenne/event/XMPPBridgeFactoryTest.java    |  47 ++++---
 .../cayenne/event/XMPPBridgeProviderTest.java   | 130 +++++++++++++++++++
 30 files changed, 1179 insertions(+), 483 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java
index 5445473..e16d834 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java
@@ -19,17 +19,6 @@
 
 package org.apache.cayenne.access;
 
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentMap;
-
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataObject;
 import org.apache.cayenne.DataRow;
@@ -38,7 +27,6 @@ import org.apache.cayenne.PersistenceState;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.access.event.SnapshotEvent;
 import org.apache.cayenne.event.EventBridge;
-import org.apache.cayenne.event.EventBridgeFactory;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.event.EventSubject;
 import org.apache.cayenne.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
@@ -46,9 +34,20 @@ import org.apache.commons.collections.ExtendedProperties;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
 /**
  * A fixed size cache of DataRows keyed by ObjectId.
- * 
+ *
  * @since 1.1
  */
 public class DataRowStore implements Serializable {
@@ -58,7 +57,18 @@ public class DataRowStore implements Serializable {
     // property keys
     public static final String SNAPSHOT_EXPIRATION_PROPERTY = "cayenne.DataRowStore.snapshot.expiration";
     public static final String SNAPSHOT_CACHE_SIZE_PROPERTY = "cayenne.DataRowStore.snapshot.size";
+
+    /**
+     * @deprecated since 4.0.M3 does nothing. Previously it used to check
+     * if need to create {@link EventBridge}.
+     */
+    @Deprecated
     public static final String REMOTE_NOTIFICATION_PROPERTY = "cayenne.DataRowStore.remote.notify";
+
+    /**
+     * @deprecated since 4.0.M3 {@link DataRowStoreFactory} establishes {@link EventBridge}.
+     */
+    @Deprecated
     public static final String EVENT_BRIDGE_FACTORY_PROPERTY = "cayenne.DataRowStore.EventBridge.factory";
 
     // default property values
@@ -66,15 +76,24 @@ public class DataRowStore implements Serializable {
     // default expiration time is 2 hours
     public static final long SNAPSHOT_EXPIRATION_DEFAULT = 2 * 60 * 60;
     public static final int SNAPSHOT_CACHE_SIZE_DEFAULT = 10000;
+
+    @Deprecated
     public static final boolean REMOTE_NOTIFICATION_DEFAULT = false;
 
     // use String for class name, since JavaGroups may not be around,
     // causing CNF exceptions
+    @Deprecated
     public static final String EVENT_BRIDGE_FACTORY_DEFAULT = "org.apache.cayenne.event.JavaGroupsBridgeFactory";
 
     protected String name;
     private int maxSize;
     protected ConcurrentMap<ObjectId, DataRow> snapshots;
+
+    /**
+     * @deprecated since 4.0.M3 does nothing. Previously it used to check
+     * if need to create {@link EventBridge}.
+     */
+    @Deprecated
     protected boolean notifyingRemoteListeners;
 
     protected transient EventManager eventManager;
@@ -87,13 +106,13 @@ public class DataRowStore implements Serializable {
     /**
      * Creates new DataRowStore with a specified name and a set of properties. If no
      * properties are defined, default values are used.
-     * 
-     * @param name DataRowStore name. Used to idenitfy this DataRowStore in events, etc.
-     *            Can't be null.
-     * @param properties Properties map used to configure DataRowStore parameters. Can be
-     *            null.
+     *
+     * @param name         DataRowStore name. Used to identify this DataRowStore in events, etc.
+     *                     Can't be null.
+     * @param properties   Properties map used to configure DataRowStore parameters. Can be
+     *                     null.
      * @param eventManager EventManager that should be used for posting and receiving
-     *            events.
+     *                     events.
      * @since 1.2
      */
     public DataRowStore(String name, Map properties, EventManager eventManager) {
@@ -126,14 +145,6 @@ public class DataRowStore implements Serializable {
                 SNAPSHOT_CACHE_SIZE_PROPERTY,
                 SNAPSHOT_CACHE_SIZE_DEFAULT);
 
-        boolean notifyRemote = propertiesWrapper.getBoolean(
-                REMOTE_NOTIFICATION_PROPERTY,
-                REMOTE_NOTIFICATION_DEFAULT);
-
-        String eventBridgeFactory = propertiesWrapper.getString(
-                EVENT_BRIDGE_FACTORY_PROPERTY,
-                EVENT_BRIDGE_FACTORY_DEFAULT);
-
         if (logger.isDebugEnabled()) {
             logger.debug("DataRowStore property "
                     + SNAPSHOT_EXPIRATION_PROPERTY
@@ -143,49 +154,25 @@ public class DataRowStore implements Serializable {
                     + SNAPSHOT_CACHE_SIZE_PROPERTY
                     + " = "
                     + maxSize);
-            logger.debug("DataRowStore property "
-                    + REMOTE_NOTIFICATION_PROPERTY
-                    + " = "
-                    + notifyRemote);
-            logger.debug("DataRowStore property "
-                    + EVENT_BRIDGE_FACTORY_PROPERTY
-                    + " = "
-                    + eventBridgeFactory);
         }
 
-        // init ivars from properties
-        this.notifyingRemoteListeners = notifyRemote;
-
         this.snapshots = new ConcurrentLinkedHashMap.Builder<ObjectId, DataRow>()
                 .maximumWeightedCapacity(maxSize)
                 .build();
 
-        // init event bridge only if we are notifying remote listeners
-        if (notifyingRemoteListeners) {
-            try {
-                EventBridgeFactory factory = (EventBridgeFactory) Class.forName(
-                        eventBridgeFactory).newInstance();
-
-                Collection<EventSubject> subjects = Collections
-                        .singleton(getSnapshotEventSubject());
-                String externalSubject = EventBridge
-                        .convertToExternalSubject(getSnapshotEventSubject());
-                this.remoteNotificationsHandler = factory.createEventBridge(
-                        subjects,
-                        externalSubject,
-                        properties);
-            }
-            catch (Exception ex) {
-                throw new CayenneRuntimeException("Error initializing DataRowStore.", ex);
-            }
+    }
 
-            startListeners();
-        }
+    protected void setEventBridge(EventBridge eventBridge) {
+        remoteNotificationsHandler = eventBridge;
+    }
+
+    protected EventBridge getEventBridge() {
+        return remoteNotificationsHandler;
     }
 
     /**
      * Updates cached snapshots for the list of objects.
-     * 
+     *
      * @since 1.2
      */
     void snapshotsUpdatedForObjects(List objects, List snapshots, boolean refresh) {
@@ -235,8 +222,7 @@ public class DataRowStore implements Serializable {
                         ((DataObject) object).setSnapshotVersion(cachedSnapshot
                                 .getVersion());
                         continue;
-                    }
-                    else {
+                    } else {
                         newSnapshot.setReplacesVersion(cachedSnapshot.getVersion());
                     }
                 }
@@ -300,7 +286,7 @@ public class DataRowStore implements Serializable {
 
     /**
      * Returns an EventManager associated with this DataRowStore.
-     * 
+     *
      * @since 1.2
      */
     public EventManager getEventManager() {
@@ -309,7 +295,7 @@ public class DataRowStore implements Serializable {
 
     /**
      * Sets an EventManager associated with this DataRowStore.
-     * 
+     *
      * @since 1.2
      */
     public void setEventManager(EventManager eventManager) {
@@ -554,10 +540,12 @@ public class DataRowStore implements Serializable {
         }
     }
 
+    @Deprecated
     public boolean isNotifyingRemoteListeners() {
         return notifyingRemoteListeners;
     }
 
+    @Deprecated
     public void setNotifyingRemoteListeners(boolean notifyingRemoteListeners) {
         this.notifyingRemoteListeners = notifyingRemoteListeners;
     }
@@ -580,8 +568,7 @@ public class DataRowStore implements Serializable {
         if (remoteNotificationsHandler != null) {
             try {
                 remoteNotificationsHandler.shutdown();
-            }
-            catch (Exception ex) {
+            } catch (Exception ex) {
                 logger.info("Exception shutting down EventBridge.", ex);
             }
             remoteNotificationsHandler = null;
@@ -613,8 +600,7 @@ public class DataRowStore implements Serializable {
                     remoteNotificationsHandler.startup(
                             eventManager,
                             EventBridge.RECEIVE_LOCAL_EXTERNAL);
-                }
-                catch (Exception ex) {
+                } catch (Exception ex) {
                     throw new CayenneRuntimeException(
                             "Error initializing DataRowStore.",
                             ex);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
index f6f67fc..a3397b3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
@@ -19,9 +19,12 @@
 
 package org.apache.cayenne.access;
 
+import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.di.DIRuntimeException;
 import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.event.EventBridge;
 import org.apache.cayenne.event.EventManager;
 
 import java.util.Map;
@@ -34,6 +37,9 @@ import java.util.Map;
 public class DefaultDataRowStoreFactory implements DataRowStoreFactory {
 
     @Inject
+    protected Injector injector;
+
+    @Inject
     protected EventManager eventManager;
 
     @Inject(Constants.DATA_ROW_STORE_PROPERTIES_MAP)
@@ -41,7 +47,19 @@ public class DefaultDataRowStoreFactory implements DataRowStoreFactory {
 
     @Override
     public DataRowStore createDataRowStore(String name) throws DIRuntimeException {
-        return new DataRowStore(name, properties, eventManager);
+        DataRowStore store = new DataRowStore(
+                name,
+                properties,
+                eventManager);
+
+        try {
+            store.setEventBridge(injector.getInstance(EventBridge.class));
+            store.startListeners();
+        } catch (Exception ex) {
+            throw new CayenneRuntimeException("Error initializing DataRowStore.", ex);
+        }
+
+        return store;
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/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 18c42cd..9761790 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
@@ -272,4 +272,28 @@ public interface Constants {
      */
     public static final String DATA_ROW_STORE_PROPERTIES_MAP = "cayenne.server.data_row_store";
 
+    /**
+     * A DI container key for the Map&lt;String, String&gt; storing
+     * {@link org.apache.cayenne.event.JMSBridge} properties
+     *
+     * @since 4.0
+     */
+    public static final String JMS_BRIDGE_PROPERTIES_MAP = "cayenne.server.jms_bridge";
+
+    /**
+     * A DI container key for the Map&lt;String, String&gt; storing
+     * {@link org.apache.cayenne.event.JavaGroupsBridge} properties
+     *
+     * @since 4.0
+     */
+    public static final String JAVA_GROUPS_BRIDGE_PROPERTIES_MAP = "cayenne.server.java_group_bridge";
+
+    /**
+     * A DI container key for the Map&lt;String, String&gt; storing
+     * {@link org.apache.cayenne.event.XMPPBridge} properties
+     *
+     * @since 4.0
+     */
+    public static final String XMPP_BRIDGE_PROPERTIES_MAP = "cayenne.server.xmpp_bridge";
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/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 b7b34c7..c630155 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
@@ -23,6 +23,7 @@ import org.apache.cayenne.DataChannel;
 import org.apache.cayenne.DataChannelFilter;
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataNode;
+import org.apache.cayenne.access.DataRowStoreFactory;
 import org.apache.cayenne.cache.NestedQueryCache;
 import org.apache.cayenne.cache.QueryCache;
 import org.apache.cayenne.configuration.ConfigurationTree;
@@ -113,6 +114,7 @@ public class DataDomainProvider implements Provider<DataDomain> {
 		dataDomain.setQueryCache(new NestedQueryCache(queryCache));
 		dataDomain.setEntitySorter(injector.getInstance(EntitySorter.class));
 		dataDomain.setEventManager(injector.getInstance(EventManager.class));
+		dataDomain.setDataRowStoreFactory(injector.getInstance(DataRowStoreFactory.class));
 
 		dataDomain.initWithProperties(descriptor.getProperties());
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/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 2f8590d..8e24e38 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
@@ -92,6 +92,8 @@ import org.apache.cayenne.di.Module;
 import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
 import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
 import org.apache.cayenne.event.DefaultEventManager;
+import org.apache.cayenne.event.EventBridgeProvider;
+import org.apache.cayenne.event.EventBridge;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.log.CommonsJdbcEventLogger;
 import org.apache.cayenne.log.JdbcEventLogger;
@@ -292,8 +294,10 @@ public class ServerModule implements Module {
 
         binder.bind(QueryCache.class).toProvider(MapQueryCacheProvider.class);
 
-		binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
-        binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);// a service to provide the main stack DataDomain
+        binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+        binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
+
+		// a service to provide the main stack DataDomain
 		binder.bind(DataDomain.class).toProvider(DataDomainProvider.class);
 
         binder.bind(DataNodeFactory.class).to(DefaultDataNodeFactory.class);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeFactory.java
index 7d5ecdc..dc59d0d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeFactory.java
@@ -30,7 +30,7 @@ import java.util.Map;
 public interface EventBridgeFactory {
 
     /**
-     * Creates an EventBridge with the specified parameters.
+     * Creates an {@link EventBridge} with the specified parameters.
      * 
      * @since 1.2
      */

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java
new file mode 100644
index 0000000..ef78fb7
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java
@@ -0,0 +1,60 @@
+/*****************************************************************
+ *   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.event;
+
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.access.DataRowStore;
+import org.apache.cayenne.di.DIRuntimeException;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+
+import java.util.Collections;
+
+public class EventBridgeProvider implements Provider<EventBridge> {
+
+    @Inject
+    protected DataDomain dataDomain;
+
+    @Override
+    public EventBridge get() throws DIRuntimeException {
+        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class.getClass(), dataDomain.getName());
+
+        return new EventBridge(
+                Collections.singleton(snapshotEventSubject),
+                EventBridge.convertToExternalSubject(snapshotEventSubject)) {
+
+            @Override
+            protected void startupExternal() throws Exception {
+
+            }
+
+            @Override
+            protected void shutdownExternal() throws Exception {
+
+            }
+
+            @Override
+            protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
+
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridge.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridge.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridge.java
index 41ce7eb..0b746fc 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridge.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridge.java
@@ -19,8 +19,7 @@
 
 package org.apache.cayenne.event;
 
-import java.io.Serializable;
-import java.util.Collection;
+import org.apache.cayenne.util.IDUtil;
 
 import javax.jms.Message;
 import javax.jms.MessageFormatException;
@@ -37,8 +36,9 @@ import javax.naming.Context;
 import javax.naming.InitialContext;
 import javax.naming.NameNotFoundException;
 import javax.naming.NamingException;
-
-import org.apache.cayenne.util.IDUtil;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
 
 /**
  * Implementation of EventBridge that passes and receives events via JMS (Java Messaging
@@ -49,8 +49,14 @@ import org.apache.cayenne.util.IDUtil;
  */
 public class JMSBridge extends EventBridge implements MessageListener {
 
+    // this is an OpenJMS default for the factory name. Likely it won't work with
+    // anything else
+    public static final String TOPIC_CONNECTION_FACTORY_DEFAULT = "JmsTopicConnectionFactory";
+
+    public static final String TOPIC_CONNECTION_FACTORY_PROPERTY = "cayenne.JMSBridge.topic.connection.factory";
+
     static final String VM_ID = new String(IDUtil.pseudoUniqueByteSequence16());
-    static final String VM_ID_PROPERRTY = "VM_ID";
+    static final String VM_ID_PROPERTY = "VM_ID";
 
     protected String topicConnectionFactoryName;
 
@@ -72,13 +78,28 @@ public class JMSBridge extends EventBridge implements MessageListener {
     }
 
     /**
+     * @since 4.0
+     */
+    public JMSBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) {
+        super(localSubjects, externalSubject);
+
+        // configure properties
+        String topicConnectionFactory = properties
+                .get(TOPIC_CONNECTION_FACTORY_PROPERTY);
+
+        this.topicConnectionFactoryName = (topicConnectionFactory != null)
+                ? topicConnectionFactory
+                : TOPIC_CONNECTION_FACTORY_DEFAULT;
+    }
+
+    /**
      * JMS MessageListener implementation. Injects received events to the EventManager
      * local event queue.
      */
     public void onMessage(Message message) {
 
         try {
-            Object vmID = message.getObjectProperty(JMSBridge.VM_ID_PROPERRTY);
+            Object vmID = message.getObjectProperty(JMSBridge.VM_ID_PROPERTY);
             if (JMSBridge.VM_ID.equals(vmID)) {
                 return;
             }
@@ -235,7 +256,7 @@ public class JMSBridge extends EventBridge implements MessageListener {
     protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
         ObjectMessage message = sendSession
                 .createObjectMessage(eventToMessageObject(localEvent));
-        message.setObjectProperty(JMSBridge.VM_ID_PROPERRTY, JMSBridge.VM_ID);
+        message.setObjectProperty(JMSBridge.VM_ID_PROPERTY, JMSBridge.VM_ID);
         publisher.publish(message);
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
index d727365..b7772d8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
@@ -29,26 +29,11 @@ import java.util.Map;
  */
 public class JMSBridgeFactory implements EventBridgeFactory {
 
-    // this is an OpenJMS default for the factory name. Likely it won't work with
-    // anything else
-    public static final String TOPIC_CONNECTION_FACTORY_DEFAULT = "JmsTopicConnectionFactory";
-
-    public static final String TOPIC_CONNECTION_FACTORY_PROPERTY = "cayenne.JMSBridge.topic.connection.factory";
-
     /**
      * @since 1.2
      */
     public EventBridge createEventBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) {
-        JMSBridge bridge = new JMSBridge(localSubjects, externalSubject);
-
-        // configure properties
-        String topicConnectionFactory = properties
-                .get(TOPIC_CONNECTION_FACTORY_PROPERTY);
-
-        bridge.setTopicConnectionFactoryName(topicConnectionFactory != null
-                ? topicConnectionFactory
-                : TOPIC_CONNECTION_FACTORY_DEFAULT);
-
-        return bridge;
+        return new JMSBridge(localSubjects, externalSubject, properties);
     }
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
new file mode 100644
index 0000000..217c5b3
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
@@ -0,0 +1,50 @@
+/*****************************************************************
+ *   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.event;
+
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.access.DataRowStore;
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.di.DIRuntimeException;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class JMSBridgeProvider implements Provider<EventBridge> {
+
+    @Inject
+    protected DataDomain dataDomain;
+
+    @Inject(Constants.JMS_BRIDGE_PROPERTIES_MAP)
+    Map<String, String> properties;
+
+    @Override
+    public EventBridge get() throws DIRuntimeException {
+        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class, dataDomain.getName());;
+
+        return new JMSBridge(
+                Collections.singleton(snapshotEventSubject),
+                EventBridge.convertToExternalSubject(snapshotEventSubject),
+                properties);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
index e7438ef..44ea4f0 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
@@ -19,15 +19,16 @@
 
 package org.apache.cayenne.event;
 
-import java.io.Serializable;
-import java.util.Collection;
-
 import org.jgroups.Channel;
 import org.jgroups.JChannel;
 import org.jgroups.Message;
 import org.jgroups.MessageListener;
 import org.jgroups.blocks.PullPushAdapter;
 
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+
 /**
  * Implementation of EventBridge that passes and receives events via JavaGroups
  * communication software.
@@ -36,6 +37,17 @@ import org.jgroups.blocks.PullPushAdapter;
  */
 public class JavaGroupsBridge extends EventBridge implements MessageListener {
 
+    public static final String MCAST_ADDRESS_DEFAULT = "228.0.0.5";
+    public static final String MCAST_PORT_DEFAULT = "22222";
+
+    public static final String MCAST_ADDRESS_PROPERTY = "cayenne.JavaGroupsBridge.mcast.address";
+    public static final String MCAST_PORT_PROPERTY = "cayenne.JavaGroupsBridge.mcast.port";
+
+    /**
+     * Defines a property for JavaGroups XML configuration file.
+     */
+    public static final String JGROUPS_CONFIG_URL_PROPERTY = "javagroupsbridge.config.url";
+
     // TODO: Meaning of "state" in JGroups is not yet clear to me
     protected byte[] state;
 
@@ -59,6 +71,21 @@ public class JavaGroupsBridge extends EventBridge implements MessageListener {
         super(localSubjects, externalSubject);
     }
 
+    /**
+     * @since 4.0
+     */
+    public JavaGroupsBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) {
+        super(localSubjects, externalSubject);
+
+        // configure properties
+        String multicastAddress = properties.get(MCAST_ADDRESS_PROPERTY);
+        String multicastPort = properties.get(MCAST_PORT_PROPERTY);
+
+        this.configURL = properties.get(JGROUPS_CONFIG_URL_PROPERTY);
+        this.multicastAddress = (multicastAddress != null) ? multicastAddress : MCAST_ADDRESS_DEFAULT;
+        this.multicastPort = (multicastPort != null) ? multicastPort : MCAST_PORT_DEFAULT;
+    }
+
     public String getConfigURL() {
         return configURL;
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
index 8ad7efe..302e5ca 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
@@ -19,35 +19,19 @@
 
 package org.apache.cayenne.event;
 
-import java.lang.reflect.Constructor;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Map;
 
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.reflect.PropertyUtils;
-
 /**
  * Factory to create JavaGroupsBridge instances. If JavaGroups library is not installed
  * this factory will return a noop EventBridge as a failover mechanism.
- *
+ * <p/>
  * For further information about JavaGroups consult the <a href="http://www.jgroups.org/">documentation</a>.
- * 
+ *
  * @since 1.1
  */
 public class JavaGroupsBridgeFactory implements EventBridgeFactory {
 
-    public static final String MCAST_ADDRESS_DEFAULT = "228.0.0.5";
-    public static final String MCAST_PORT_DEFAULT = "22222";
-
-    public static final String MCAST_ADDRESS_PROPERTY = "cayenne.JavaGroupsBridge.mcast.address";
-    public static final String MCAST_PORT_PROPERTY = "cayenne.JavaGroupsBridge.mcast.port";
-
-    /**
-     * Defines a property for JavaGroups XML configuration file.
-     */
-    public static final String JGROUPS_CONFIG_URL_PROPERTY = "javagroupsbridge.config.url";
-
     /**
      * Creates a JavaGroupsBridge instance. Since JavaGroups is not shipped with Cayenne
      * and should be installed separately, a common misconfiguration problem may be the
@@ -59,94 +43,7 @@ public class JavaGroupsBridgeFactory implements EventBridgeFactory {
             Collection<EventSubject> localSubjects,
             String externalSubject,
             Map<String, String> properties) {
-
-        try {
-            // sniff JavaGroups presence
-            Class.forName("org.jgroups.Channel");
-            return createJavaGroupsBridge(localSubjects, externalSubject, properties);
-        }
-        catch (Exception ex) {
-            // recover from no JavaGroups
-            return createNoopBridge();
-        }
-    }
-
-    private EventBridge createNoopBridge() {
-        return new NoopEventBridge();
+        return new JavaGroupsBridge(localSubjects, externalSubject, properties);
     }
 
-    private EventBridge createJavaGroupsBridge(
-            Collection<EventSubject> localSubjects,
-            String externalSubject,
-            Map<String, String> properties) {
-
-        // create JavaGroupsBridge using reflection to avoid triggering
-        // ClassNotFound exceptions due to JavaGroups absence.
-
-        try {
-            Constructor<?> c = Class
-                    .forName("org.apache.cayenne.event.JavaGroupsBridge")
-                    .getConstructor(Collection.class, String.class);
-
-            Object bridge = c.newInstance(localSubjects, externalSubject);
-
-            // configure properties
-            String multicastAddress = properties.get(MCAST_ADDRESS_PROPERTY);
-            String multicastPort = properties.get(MCAST_PORT_PROPERTY);
-            String configURL = properties.get(JGROUPS_CONFIG_URL_PROPERTY);
-
-            PropertyUtils.setProperty(bridge, "configURL", configURL);
-            PropertyUtils.setProperty(
-                    bridge,
-                    "multicastAddress",
-                    multicastAddress != null ? multicastAddress : MCAST_ADDRESS_DEFAULT);
-            PropertyUtils.setProperty(bridge, "multicastPort", multicastPort != null
-                    ? multicastPort
-                    : MCAST_PORT_DEFAULT);
-
-            return (EventBridge) bridge;
-        }
-        catch (Exception ex) {
-            throw new CayenneRuntimeException("Error creating JavaGroupsBridge", ex);
-        }
-    }
-
-    // mockup EventBridge
-    class NoopEventBridge extends EventBridge {
-
-        public NoopEventBridge() {
-            super(Collections.<EventSubject>emptySet(), null);
-        }
-
-        @Override
-        public boolean receivesExternalEvents() {
-            return false;
-        }
-
-        @Override
-        public boolean receivesLocalEvents() {
-            return false;
-        }
-
-        @Override
-        protected void startupExternal() {
-        }
-
-        @Override
-        protected void shutdownExternal() {
-        }
-
-        @Override
-        protected void sendExternalEvent(CayenneEvent localEvent) {
-        }
-
-        @Override
-        public void startup(EventManager eventManager, int mode, Object eventsSource) {
-            this.eventManager = eventManager;
-        }
-
-        @Override
-        public void shutdown() {
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
new file mode 100644
index 0000000..191872d
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
@@ -0,0 +1,50 @@
+/*****************************************************************
+ *   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.event;
+
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.access.DataRowStore;
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.di.DIRuntimeException;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class JavaGroupsBridgeProvider implements Provider<EventBridge> {
+
+    @Inject
+    protected DataDomain dataDomain;
+
+    @Inject(Constants.JAVA_GROUPS_BRIDGE_PROPERTIES_MAP)
+    Map<String, String> properties;
+
+    @Override
+    public EventBridge get() throws DIRuntimeException {
+        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class, dataDomain.getName());;
+
+        return new JavaGroupsBridge(
+                Collections.singleton(snapshotEventSubject),
+                EventBridge.convertToExternalSubject(snapshotEventSubject),
+                properties);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridge.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridge.java b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridge.java
index a533f0c..10a1386 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridge.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridge.java
@@ -19,13 +19,9 @@
 
 package org.apache.cayenne.event;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.Collection;
-import java.util.Collections;
-
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.util.Base64Codec;
+import org.apache.cayenne.util.Util;
 import org.jivesoftware.smack.GroupChat;
 import org.jivesoftware.smack.PacketListener;
 import org.jivesoftware.smack.SSLXMPPConnection;
@@ -33,9 +29,14 @@ import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException;
 import org.jivesoftware.smack.packet.Message;
 import org.jivesoftware.smack.packet.Packet;
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.util.Base64Codec;
-import org.apache.cayenne.util.Util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
 
 /**
  * An EventBridge implementation based on XMPP protocol and Smack XMPP client library.
@@ -52,6 +53,22 @@ import org.apache.cayenne.util.Util;
  */
 public class XMPPBridge extends EventBridge {
 
+    public static final String XMPP_HOST_PROPERTY = "cayenne.XMPPBridge.xmppHost";
+
+    /**
+     * An optional property, port 5222 is used as default XMPP port.
+     */
+    public static final String XMPP_PORT_PROPERTY = "cayenne.XMPPBridge.xmppPort";
+
+    /**
+     * An optional property, "conference" is used as default chat service.
+     */
+    public static final String XMPP_CHAT_SERVICE_PROPERTY = "cayenne.XMPPBridge.xmppChatService";
+
+    public static final String XMPP_SECURE_CONNECTION_PROPERTY = "cayenne.XMPPBridge.xmppSecure";
+    public static final String XMPP_LOGIN_PROPERTY = "cayenne.XMPPBridge.xmppLogin";
+    public static final String XMPP_PASSWORD_PROPERTY = "cayenne.XMPPBridge.xmppPassword";
+
     static final String DEFAULT_CHAT_SERVICE = "conference";
     static final int DEFAULT_XMPP_PORT = 5222;
     static final int DEFAULT_XMPP_SECURE_PORT = 5223;
@@ -86,6 +103,31 @@ public class XMPPBridge extends EventBridge {
         this.sessionHandle = "cayenne-xmpp-" + System.currentTimeMillis();
     }
 
+    public XMPPBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) {
+        this(localSubjects, externalSubject);
+
+        this.chatService = properties.get(XMPP_CHAT_SERVICE_PROPERTY);
+        this.xmppHost = properties.get(XMPP_HOST_PROPERTY);
+
+        this.loginId = properties.get(XMPP_LOGIN_PROPERTY);
+        this.password = properties.get(XMPP_PASSWORD_PROPERTY);
+
+        String secureConnectionString = properties.get(XMPP_SECURE_CONNECTION_PROPERTY);
+        secureConnection = "true".equalsIgnoreCase(secureConnectionString);
+
+        String portString = properties.get(XMPP_PORT_PROPERTY);
+        int port = -1;
+        if (portString != null) {
+
+            try {
+                this.xmppPort = Integer.parseInt(portString);
+            }
+            catch (NumberFormatException e) {
+                throw new CayenneRuntimeException("Invalid port: " + portString);
+            }
+        }
+    }
+
     public String getXmppHost() {
         return xmppHost;
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
index bb72158..7934752 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
@@ -22,8 +22,6 @@ package org.apache.cayenne.event;
 import java.util.Collection;
 import java.util.Map;
 
-import org.apache.cayenne.CayenneRuntimeException;
-
 /**
  * A factory of XMPPBridge. Note that to deploy an XMPPBridge, you need to have
  * <em>smack.jar</em> library in the runtime.
@@ -32,59 +30,12 @@ import org.apache.cayenne.CayenneRuntimeException;
  */
 public class XMPPBridgeFactory implements EventBridgeFactory {
 
-    public static final String XMPP_HOST_PROPERTY = "cayenne.XMPPBridge.xmppHost";
-
-    /**
-     * An optional property, port 5222 is used as default XMPP port.
-     */
-    public static final String XMPP_PORT_PROPERTY = "cayenne.XMPPBridge.xmppPort";
-
-    /**
-     * An optional property, "conference" is used as default chat service.
-     */
-    public static final String XMPP_CHAT_SERVICE_PROPERTY = "cayenne.XMPPBridge.xmppChatService";
-
-    public static final String XMPP_SECURE_CONNECTION_PROPERTY = "cayenne.XMPPBridge.xmppSecure";
-    public static final String XMPP_LOGIN_PROPERTY = "cayenne.XMPPBridge.xmppLogin";
-    public static final String XMPP_PASSWORD_PROPERTY = "cayenne.XMPPBridge.xmppPassword";
-
     @Override
     public EventBridge createEventBridge(
             Collection<EventSubject> localSubjects,
             String externalSubject,
             Map<String, String> properties) {
-
-        String chatService = properties.get(XMPP_CHAT_SERVICE_PROPERTY);
-        String host = properties.get(XMPP_HOST_PROPERTY);
-
-        String loginId = properties.get(XMPP_LOGIN_PROPERTY);
-        String password = properties.get(XMPP_PASSWORD_PROPERTY);
-
-        String secureConnectionString = properties
-                .get(XMPP_SECURE_CONNECTION_PROPERTY);
-        boolean secureConnection = "true".equalsIgnoreCase(secureConnectionString);
-
-        String portString = properties.get(XMPP_PORT_PROPERTY);
-        int port = -1;
-        if (portString != null) {
-
-            try {
-                port = Integer.parseInt(portString);
-            }
-            catch (NumberFormatException e) {
-                throw new CayenneRuntimeException("Invalid port: " + portString);
-            }
-        }
-
-        XMPPBridge bridge = new XMPPBridge(localSubjects, externalSubject);
-
-        bridge.setXmppHost(host);
-        bridge.setXmppPort(port);
-        bridge.setChatService(chatService);
-        bridge.setSecureConnection(secureConnection);
-        bridge.setLoginId(loginId);
-        bridge.setPassword(password);
-
-        return bridge;
+        return new XMPPBridge(localSubjects, externalSubject, properties);
     }
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
new file mode 100644
index 0000000..ae577f2
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
@@ -0,0 +1,50 @@
+/*****************************************************************
+ *   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.event;
+
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.access.DataRowStore;
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.di.DIRuntimeException;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class XMPPBridgeProvider implements Provider<EventBridge> {
+
+    @Inject
+    protected DataDomain dataDomain;
+
+    @Inject(Constants.XMPP_BRIDGE_PROPERTIES_MAP)
+    Map<String, String> properties;
+
+    @Override
+    public EventBridge get() throws DIRuntimeException {
+        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class.getClass(), dataDomain.getName());;
+
+        return new XMPPBridge(
+                Collections.singleton(snapshotEventSubject),
+                EventBridge.convertToExternalSubject(snapshotEventSubject),
+                properties);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java
deleted file mode 100644
index 743368c..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java
+++ /dev/null
@@ -1,119 +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.access;
-
-import org.apache.cayenne.configuration.Constants;
-import org.apache.cayenne.configuration.DefaultRuntimeProperties;
-import org.apache.cayenne.configuration.RuntimeProperties;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Binder;
-import org.apache.cayenne.di.DIBootstrap;
-import org.apache.cayenne.di.Injector;
-import org.apache.cayenne.di.Module;
-import org.apache.cayenne.event.DefaultEventManager;
-import org.apache.cayenne.event.EventManager;
-import org.apache.cayenne.log.CommonsJdbcEventLogger;
-import org.apache.cayenne.log.JdbcEventLogger;
-import org.apache.cayenne.tx.DefaultTransactionFactory;
-import org.apache.cayenne.tx.DefaultTransactionManager;
-import org.apache.cayenne.tx.TransactionFactory;
-import org.apache.cayenne.tx.TransactionManager;
-import org.apache.cayenne.unit.di.server.CayenneProjects;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-@UseServerRuntime(CayenneProjects.MULTI_TIER_PROJECT)
-public class DataRowStoreFactoryIT extends ServerCase {
-
-    @Test
-    public void testGetDataRowStore() throws Exception {
-        ServerRuntime runtime = getUnitTestInjector().getInstance(ServerRuntime.class);
-        DataRowStore dataStore = runtime.getInjector().getInstance(DataRowStoreFactory.class)
-                .createDataRowStore("test");
-
-        assertNotNull(dataStore);
-    }
-
-    @Test
-    public void testGetDataRowStoreWithParameters() {
-        final DataDomain DOMAIN = new DataDomain("test");
-        final EventManager EVENT_MANAGER = new DefaultEventManager();
-        final int CACHE_SIZE = 500;
-        final int EXPIRATION_PROPERTY = 60 * 60 * 24;
-
-        Module testModule = new Module() {
-
-            public void configure(Binder binder) {
-                binder.bindMap(Constants.PROPERTIES_MAP);
-                binder.bind(DataDomain.class).toInstance(DOMAIN);
-                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
-                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
-                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
-                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
-                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
-                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
-                binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP)
-                        .put(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, String.valueOf(CACHE_SIZE))
-                        .put(DataRowStore.SNAPSHOT_EXPIRATION_PROPERTY, String.valueOf(EXPIRATION_PROPERTY));
-            }
-        };
-
-        Injector injector = DIBootstrap.createInjector(testModule);
-        DataRowStore dataStore = injector.getInstance(DataRowStoreFactory.class)
-                .createDataRowStore("test");
-
-        assertNotNull(dataStore);
-        assertEquals(dataStore.maximumSize(), CACHE_SIZE);
-    }
-
-    @Test
-    public void testGetDataRowStoreWithBridge() {
-        final DataDomain DOMAIN = new DataDomain("test");
-        final EventManager EVENT_MANAGER = new DefaultEventManager();
-
-        Module testModule = new Module() {
-
-            public void configure(Binder binder) {
-                binder.bindMap(Constants.PROPERTIES_MAP);
-                binder.bind(DataDomain.class).toInstance(DOMAIN);
-                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
-                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
-                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
-                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
-                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
-                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
-                binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
-            }
-        };
-
-        Injector injector = DIBootstrap.createInjector(testModule);
-        DataRowStore dataStore = injector.getInstance(DataRowStoreFactory.class)
-                .createDataRowStore("test");
-
-        dataStore.stopListeners();
-        dataStore.startListeners();
-        dataStore.shutdown();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java
index 54ce5a1..879e98d 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java
@@ -64,38 +64,6 @@ public class DataRowStoreIT extends ServerCase {
         assertEquals("cacheXYZ", cache.getName());
         assertNotNull(cache.getSnapshotEventSubject());
         assertTrue(cache.getSnapshotEventSubject().getSubjectName().contains("cacheXYZ"));
-
-        assertEquals(DataRowStore.REMOTE_NOTIFICATION_DEFAULT, cache
-                .isNotifyingRemoteListeners());
-    }
-
-    @Test
-    public void testConstructorWithProperties() {
-        Map<Object, Object> props = new HashMap<Object, Object>();
-        props.put(DataRowStore.REMOTE_NOTIFICATION_PROPERTY, String
-                .valueOf(!DataRowStore.REMOTE_NOTIFICATION_DEFAULT));
-        cache = new DataRowStore(
-                "cacheXYZ",
-                props,
-                null);
-        assertEquals("cacheXYZ", cache.getName());
-        assertEquals(!DataRowStore.REMOTE_NOTIFICATION_DEFAULT, cache
-                .isNotifyingRemoteListeners());
-    }
-
-    @Test
-    public void testNotifyingRemoteListeners() {
-        cache = new DataRowStore(
-                "cacheXYZ",
-                Collections.EMPTY_MAP,
-                null);
-
-        assertEquals(DataRowStore.REMOTE_NOTIFICATION_DEFAULT, cache
-                .isNotifyingRemoteListeners());
-
-        cache.setNotifyingRemoteListeners(!DataRowStore.REMOTE_NOTIFICATION_DEFAULT);
-        assertEquals(!DataRowStore.REMOTE_NOTIFICATION_DEFAULT, cache
-                .isNotifyingRemoteListeners());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java
new file mode 100644
index 0000000..2621443
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java
@@ -0,0 +1,123 @@
+/*****************************************************************
+ *   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.access;
+
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.configuration.DefaultRuntimeProperties;
+import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.DIBootstrap;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.event.DefaultEventManager;
+import org.apache.cayenne.event.EventBridge;
+import org.apache.cayenne.event.EventBridgeProvider;
+import org.apache.cayenne.event.EventManager;
+import org.apache.cayenne.event.MockEventBridge;
+import org.apache.cayenne.event.MockEventBridgeProvider;
+import org.apache.cayenne.log.CommonsJdbcEventLogger;
+import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.tx.DefaultTransactionFactory;
+import org.apache.cayenne.tx.DefaultTransactionManager;
+import org.apache.cayenne.tx.TransactionFactory;
+import org.apache.cayenne.tx.TransactionManager;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@UseServerRuntime(CayenneProjects.MULTI_TIER_PROJECT)
+public class DefaultDataRowStoreFactoryIT extends ServerCase {
+
+    @Test
+    public void testGetDataRowStore() throws Exception {
+        ServerRuntime runtime = getUnitTestInjector().getInstance(ServerRuntime.class);
+        DataRowStore dataStore = runtime.getInjector().getInstance(DataRowStoreFactory.class)
+                .createDataRowStore("test");
+
+        assertNotNull(dataStore);
+    }
+
+    @Test
+    public void testGetDataRowStoreWithParameters() {
+        final DataDomain DOMAIN = new DataDomain("test");
+        final EventManager EVENT_MANAGER = new DefaultEventManager();
+        final int CACHE_SIZE = 500;
+        final int EXPIRATION_PROPERTY = 60 * 60 * 24;
+
+        Module testModule = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);
+                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+                binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP)
+                        .put(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, String.valueOf(CACHE_SIZE))
+                        .put(DataRowStore.SNAPSHOT_EXPIRATION_PROPERTY, String.valueOf(EXPIRATION_PROPERTY));
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(testModule);
+        DataRowStore dataStore = injector.getInstance(DataRowStoreFactory.class)
+                .createDataRowStore("test");
+
+        assertNotNull(dataStore);
+        assertEquals(dataStore.maximumSize(), CACHE_SIZE);
+    }
+
+    @Test
+    public void testGetDataRowStoreWithBridge() {
+        final DataDomain DOMAIN = new DataDomain("test");
+        final EventManager EVENT_MANAGER = new DefaultEventManager();
+
+        Module testModule = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(MockEventBridgeProvider.class);
+                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+                binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(testModule);
+        DataRowStore dataStore = injector.getInstance(DataRowStoreFactory.class)
+                .createDataRowStore("test");
+
+        assertEquals(dataStore.getEventBridge().getClass(), MockEventBridge.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/access/MockDataRowStore.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/MockDataRowStore.java b/cayenne-server/src/test/java/org/apache/cayenne/access/MockDataRowStore.java
index dba5c98..76ac2cb 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/MockDataRowStore.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/MockDataRowStore.java
@@ -19,13 +19,13 @@
 
 package org.apache.cayenne.access;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.event.MockEventManager;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * A "lightweight" DataRowStore.
  */
@@ -35,7 +35,6 @@ public class MockDataRowStore extends DataRowStore {
 
     static {
         TEST_DEFAULTS.put(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, new Integer(10));
-        TEST_DEFAULTS.put(DataRowStore.REMOTE_NOTIFICATION_PROPERTY, Boolean.FALSE);
     }
 
     public MockDataRowStore() {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
index 0304a2e..32477cb 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
@@ -35,6 +35,8 @@ import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.DIBootstrap;
 import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.di.Module;
+import org.apache.cayenne.event.EventBridgeProvider;
+import org.apache.cayenne.event.EventBridge;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.event.MockEventManager;
 import org.apache.cayenne.log.CommonsJdbcEventLogger;
@@ -78,6 +80,8 @@ public class DataContextFactoryTest {
                 binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
                 binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
                 binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+                binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);
+                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
                 binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
             }
         };
@@ -116,6 +120,7 @@ public class DataContextFactoryTest {
                 binder.bind(ObjectStoreFactory.class).to(DefaultObjectStoreFactory.class);
                 binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
                 binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);
                 binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
                 binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
             }
@@ -123,6 +128,8 @@ public class DataContextFactoryTest {
 
         Injector injector = DIBootstrap.createInjector(testModule);
 
+        domain.setDataRowStoreFactory(injector.getInstance(DataRowStoreFactory.class));
+
         DataContextFactory factory = new DataContextFactory();
         injector.injectMembers(factory);
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/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 1828a0c..54831de 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
@@ -22,6 +22,8 @@ import org.apache.cayenne.ConfigurationException;
 import org.apache.cayenne.DataChannel;
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataNode;
+import org.apache.cayenne.access.DataRowStoreFactory;
+import org.apache.cayenne.access.DefaultDataRowStoreFactory;
 import org.apache.cayenne.access.dbsync.DefaultSchemaUpdateStrategyFactory;
 import org.apache.cayenne.access.dbsync.SchemaUpdateStrategyFactory;
 import org.apache.cayenne.access.dbsync.SkipSchemaUpdateStrategy;
@@ -70,6 +72,8 @@ import org.apache.cayenne.di.Key;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
 import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
+import org.apache.cayenne.event.EventBridge;
+import org.apache.cayenne.event.EventBridgeProvider;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.event.MockEventManager;
 import org.apache.cayenne.log.CommonsJdbcEventLogger;
@@ -192,6 +196,10 @@ public class DataDomainProviderTest {
 				binder.bind(RowReaderFactory.class).toInstance(mock(RowReaderFactory.class));
 				binder.bind(DataNodeFactory.class).to(DefaultDataNodeFactory.class);
 				binder.bind(SQLTemplateProcessor.class).toInstance(mock(SQLTemplateProcessor.class));
+
+                binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);
+                binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+                binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
 			}
 		};
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/event/JGroupsBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JGroupsBridgeFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/JGroupsBridgeFactoryTest.java
deleted file mode 100644
index 3a6b6c1..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/event/JGroupsBridgeFactoryTest.java
+++ /dev/null
@@ -1,46 +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.event;
-
-import org.junit.Test;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import static org.junit.Assert.*;
-
-/**
- */
-public class JGroupsBridgeFactoryTest {
-
-    @Test
-    public void testCreateEventBridge() throws Exception {
-        Collection subjects = Collections.singleton(new EventSubject("test"));
-        EventBridge bridge = new JavaGroupsBridgeFactory().createEventBridge(
-                subjects,
-                "abcd",
-                Collections.EMPTY_MAP);
-
-        assertNotNull(bridge);
-        assertTrue(bridge instanceof JavaGroupsBridge);
-        assertEquals(subjects, bridge.getLocalSubjects());
-        assertEquals("abcd", bridge.getExternalSubject());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java
new file mode 100644
index 0000000..e098d4e
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java
@@ -0,0 +1,77 @@
+/*****************************************************************
+ *   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.event;
+
+import org.junit.Test;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class JMSBridgeFactoryTest {
+
+    protected Collection<EventSubject> subjects = Collections.singleton(new EventSubject("test"));
+    protected String externalSubject = "subject";
+
+    @Test
+    public void testCreateEventBridge() throws Exception {
+        EventBridge bridge = new JMSBridgeFactory().createEventBridge(
+                subjects,
+                externalSubject,
+                Collections.EMPTY_MAP);
+
+        assertNotNull(bridge);
+        assertTrue(bridge instanceof JMSBridge);
+        assertEquals(subjects, bridge.getLocalSubjects());
+        assertEquals(externalSubject, bridge.getExternalSubject());
+    }
+
+    @Test
+    public void testUseProperties() throws Exception {
+        JMSBridgeFactory bridgeFactory = new JMSBridgeFactory();
+
+        Map<String, String> properties = new HashMap<String, String>();
+        properties.put(JMSBridge.TOPIC_CONNECTION_FACTORY_PROPERTY, JMSBridgeProviderTest.TOPIC_CONNECTION_FACTORY_TEST);
+
+        JMSBridge bridge = (JMSBridge) bridgeFactory.createEventBridge(
+                subjects,
+                externalSubject,
+                properties);
+
+        assertEquals(bridge.getTopicConnectionFactoryName(), JMSBridgeProviderTest.TOPIC_CONNECTION_FACTORY_TEST);
+    }
+
+    @Test
+    public void testUseDefaultProperties() throws Exception {
+        JMSBridgeFactory bridgeFactory = new JMSBridgeFactory();
+        JMSBridge bridge = (JMSBridge) bridgeFactory.createEventBridge(
+                subjects,
+                externalSubject,
+                Collections.EMPTY_MAP);
+
+        assertEquals(bridge.getTopicConnectionFactoryName(), JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java
new file mode 100644
index 0000000..c683666
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java
@@ -0,0 +1,119 @@
+/*****************************************************************
+ *   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.event;
+
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.configuration.DefaultRuntimeProperties;
+import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.DIBootstrap;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.log.CommonsJdbcEventLogger;
+import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.tx.DefaultTransactionFactory;
+import org.apache.cayenne.tx.DefaultTransactionManager;
+import org.apache.cayenne.tx.TransactionFactory;
+import org.apache.cayenne.tx.TransactionManager;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class JMSBridgeProviderTest {
+
+    private final DataDomain DOMAIN = new DataDomain("test");
+    private final EventManager EVENT_MANAGER = new DefaultEventManager();
+    protected static final String TOPIC_CONNECTION_FACTORY_TEST = "SomeTopicConnectionFactory";
+
+    @Test
+    public void testGetJMSBridge() throws Exception {
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(JMSBridgeProvider.class);
+                binder.bindMap(Constants.JMS_BRIDGE_PROPERTIES_MAP);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(module);
+        EventBridge bridge = injector.getInstance(EventBridge.class);
+
+        assertNotNull(bridge);
+        assertTrue(bridge instanceof JMSBridge);
+    }
+
+    @Test
+    public void testUseProperties() throws Exception {
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(JMSBridgeProvider.class);
+                binder.bindMap(Constants.JMS_BRIDGE_PROPERTIES_MAP)
+                        .put(JMSBridge.TOPIC_CONNECTION_FACTORY_PROPERTY, TOPIC_CONNECTION_FACTORY_TEST);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(module);
+        JMSBridge bridge = (JMSBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(JMSBridgeProviderTest.TOPIC_CONNECTION_FACTORY_TEST, bridge.getTopicConnectionFactoryName());
+    }
+
+    @Test
+    public void testUseDefaultProperties() throws Exception {
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bindMap(Constants.PROPERTIES_MAP);
+                binder.bind(DataDomain.class).toInstance(DOMAIN);
+                binder.bind(EventManager.class).toInstance(EVENT_MANAGER);
+                binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
+                binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
+                binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
+                binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+                binder.bind(EventBridge.class).toProvider(JMSBridgeProvider.class);
+                binder.bindMap(Constants.JMS_BRIDGE_PROPERTIES_MAP);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(module);
+        JMSBridge bridge = (JMSBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(bridge.getTopicConnectionFactoryName(), JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dae15cee/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java
new file mode 100644
index 0000000..3497888
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java
@@ -0,0 +1,84 @@
+/*****************************************************************
+ *   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.event;
+
+import org.junit.Test;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ */
+public class JavaGroupsBridgeFactoryTest {
+
+    protected Collection<EventSubject> subjects = Collections.singleton(new EventSubject("test"));
+    protected String externalSubject = "subject";
+
+    @Test
+    public void testCreateEventBridge() throws Exception {
+        EventBridge bridge = new JavaGroupsBridgeFactory().createEventBridge(
+                subjects,
+                externalSubject,
+                Collections.EMPTY_MAP);
+
+        assertNotNull(bridge);
+        assertTrue(bridge instanceof JavaGroupsBridge);
+        assertEquals(subjects, bridge.getLocalSubjects());
+        assertEquals(externalSubject, bridge.getExternalSubject());
+    }
+
+    @Test
+    public void testUseProperties() throws Exception {
+        JavaGroupsBridgeFactory bridgeFactory = new JavaGroupsBridgeFactory();
+
+        Map<String, String> properties = new HashMap<String, String>();
+        properties.put(JavaGroupsBridge.MCAST_ADDRESS_PROPERTY, JavaGroupsBridgeProviderTest.MCAST_ADDRESS_TEST);
+        properties.put(JavaGroupsBridge.MCAST_PORT_PROPERTY, JavaGroupsBridgeProviderTest.MCAST_PORT_TEST);
+        properties.put(JavaGroupsBridge.JGROUPS_CONFIG_URL_PROPERTY, JavaGroupsBridgeProviderTest.CONFIG_URL_TEST);
+
+        JavaGroupsBridge bridge = (JavaGroupsBridge) bridgeFactory.createEventBridge(
+                subjects,
+                externalSubject,
+                properties);
+
+        assertEquals(bridge.getMulticastAddress(), JavaGroupsBridgeProviderTest.MCAST_ADDRESS_TEST);
+        assertEquals(bridge.getMulticastPort(), JavaGroupsBridgeProviderTest.MCAST_PORT_TEST);
+        assertEquals(bridge.getConfigURL(), JavaGroupsBridgeProviderTest.CONFIG_URL_TEST);
+    }
+
+    @Test
+    public void testUseDefaultProperties() throws Exception {
+        JavaGroupsBridgeFactory bridgeFactory = new JavaGroupsBridgeFactory();
+        JavaGroupsBridge bridge = (JavaGroupsBridge) bridgeFactory.createEventBridge(
+                subjects,
+                externalSubject,
+                Collections.EMPTY_MAP);
+
+        assertEquals(bridge.getMulticastAddress(), JavaGroupsBridge.MCAST_ADDRESS_DEFAULT);
+        assertEquals(bridge.getMulticastPort(), JavaGroupsBridge.MCAST_PORT_DEFAULT);
+        assertEquals(bridge.getConfigURL(), null);
+    }
+}


[5/6] cayenne git commit: CAY-1873 final cleanup - generics in DataRowStore and related classes - rename default event bridge to NoopEventBridge and check for it in DataRowStoreFactory - return "shared cache" checkbox for DataDomain in Modeler

Posted by nt...@apache.org.
CAY-1873 final cleanup
  - generics in DataRowStore and related classes
  - rename default event bridge to NoopEventBridge and check for it in DataRowStoreFactory
  - return "shared cache" checkbox for DataDomain in Modeler

Closes #72


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

Branch: refs/heads/master
Commit: 982b1541049a479a01b480cb6c1d2ad2d65a9503
Parents: dae15ce
Author: Nikita Timofeev <st...@gmail.com>
Authored: Mon Mar 13 16:42:25 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Mon Mar 13 16:42:25 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/access/DataDomain.java   |  15 ++-
 .../org/apache/cayenne/access/DataRowStore.java | 107 +++++++++----------
 .../access/DefaultDataRowStoreFactory.java      |  37 ++++---
 .../access/HierarchicalObjectResolver.java      |  10 +-
 .../cayenne/access/PrefetchProcessorNode.java   |  66 +++++-------
 .../cayenne/access/event/SnapshotEvent.java     |  40 +++----
 .../configuration/server/ServerModule.java      |  10 +-
 .../cayenne/event/EventBridgeProvider.java      |  60 -----------
 .../apache/cayenne/event/JMSBridgeProvider.java |   2 +-
 .../cayenne/event/JavaGroupsBridgeProvider.java |   2 +-
 .../apache/cayenne/event/NoopEventBridge.java   |  43 ++++++++
 .../cayenne/event/NoopEventBridgeProvider.java  |  35 ++++++
 .../cayenne/event/XMPPBridgeProvider.java       |   2 +-
 .../apache/cayenne/access/DataRowStoreIT.java   |  28 ++---
 .../access/DefaultDataRowStoreFactoryIT.java    |   4 +-
 .../cayenne/access/event/SnapshotEventTest.java |  10 +-
 .../server/DataContextFactoryTest.java          |   6 +-
 .../server/DataDomainProviderTest.java          |   4 +-
 .../cayenne/modeler/editor/DataDomainView.java  |  20 ++++
 19 files changed, 272 insertions(+), 229 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/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 73e0c02..13746f1 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
@@ -94,7 +94,6 @@ public class DataDomain implements QueryEngine, DataChannel {
 	/**
      * @since 4.0
      */
-    @Inject
     protected DataRowStoreFactory dataRowStoreFactory;
 
     /**
@@ -654,6 +653,20 @@ public class DataDomain implements QueryEngine, DataChannel {
 	}
 
 	/**
+	 * @since 4.0
+	 */
+	public DataRowStoreFactory getDataRowStoreFactory() {
+		return dataRowStoreFactory;
+	}
+
+	/**
+	 * @since 4.0
+	 */
+	public void setDataRowStoreFactory(DataRowStoreFactory dataRowStoreFactory) {
+		this.dataRowStoreFactory = dataRowStoreFactory;
+	}
+
+	/**
 	 * @since 3.1
 	 */
 	JdbcEventLogger getJdbcEventLogger() {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java
index e16d834..fcc49a8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java
@@ -40,7 +40,6 @@ import java.io.Serializable;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentMap;
@@ -59,29 +58,28 @@ public class DataRowStore implements Serializable {
     public static final String SNAPSHOT_CACHE_SIZE_PROPERTY = "cayenne.DataRowStore.snapshot.size";
 
     /**
-     * @deprecated since 4.0.M3 does nothing. Previously it used to check
-     * if need to create {@link EventBridge}.
+     * @deprecated since 4.0 does nothing. Previously it used to check if need to create {@link EventBridge}.
      */
     @Deprecated
     public static final String REMOTE_NOTIFICATION_PROPERTY = "cayenne.DataRowStore.remote.notify";
 
     /**
-     * @deprecated since 4.0.M3 {@link DataRowStoreFactory} establishes {@link EventBridge}.
+     * @deprecated since 4.0 {@link DataRowStoreFactory} establishes {@link EventBridge}.
      */
     @Deprecated
     public static final String EVENT_BRIDGE_FACTORY_PROPERTY = "cayenne.DataRowStore.EventBridge.factory";
 
     // default property values
 
-    // default expiration time is 2 hours
-    public static final long SNAPSHOT_EXPIRATION_DEFAULT = 2 * 60 * 60;
+    public static final long SNAPSHOT_EXPIRATION_DEFAULT = 2 * 60 * 60; // default expiration time is 2 hours
     public static final int SNAPSHOT_CACHE_SIZE_DEFAULT = 10000;
 
     @Deprecated
     public static final boolean REMOTE_NOTIFICATION_DEFAULT = false;
 
-    // use String for class name, since JavaGroups may not be around,
-    // causing CNF exceptions
+    /**
+     * @deprecated since 4.0 does nothing.
+     */
     @Deprecated
     public static final String EVENT_BRIDGE_FACTORY_DEFAULT = "org.apache.cayenne.event.JavaGroupsBridgeFactory";
 
@@ -90,8 +88,7 @@ public class DataRowStore implements Serializable {
     protected ConcurrentMap<ObjectId, DataRow> snapshots;
 
     /**
-     * @deprecated since 4.0.M3 does nothing. Previously it used to check
-     * if need to create {@link EventBridge}.
+     * @deprecated since 4.0 does nothing. Previously it used to check if need to create {@link EventBridge}.
      */
     @Deprecated
     protected boolean notifyingRemoteListeners;
@@ -115,7 +112,7 @@ public class DataRowStore implements Serializable {
      *                     events.
      * @since 1.2
      */
-    public DataRowStore(String name, Map properties, EventManager eventManager) {
+    public DataRowStore(String name, Map<String, String> properties, EventManager eventManager) {
         if (name == null) {
             throw new IllegalArgumentException("DataRowStore name can't be null.");
         }
@@ -130,7 +127,7 @@ public class DataRowStore implements Serializable {
         return EventSubject.getSubject(this.getClass(), name);
     }
 
-    protected void initWithProperties(Map properties) {
+    protected void initWithProperties(Map<String, String> properties) {
         ExtendedProperties propertiesWrapper = new ExtendedProperties();
 
         if (properties != null) {
@@ -175,7 +172,7 @@ public class DataRowStore implements Serializable {
      *
      * @since 1.2
      */
-    void snapshotsUpdatedForObjects(List objects, List snapshots, boolean refresh) {
+    void snapshotsUpdatedForObjects(List<Persistent> objects, List<? extends DataRow> snapshots, boolean refresh) {
 
         int size = objects.size();
 
@@ -189,11 +186,11 @@ public class DataRowStore implements Serializable {
                             + snapshots.size());
         }
 
-        Map modified = null;
+        Map<ObjectId, DataRow> modified = null;
         Object eventPostedBy = null;
 
         for (int i = 0; i < size; i++) {
-            Persistent object = (Persistent) objects.get(i);
+            Persistent object = objects.get(i);
 
             // skip null objects... possible since 3.0 in some EJBQL results
             if (object == null) {
@@ -213,14 +210,13 @@ public class DataRowStore implements Serializable {
             DataRow cachedSnapshot = this.snapshots.get(oid);
             if (refresh || cachedSnapshot == null) {
 
-                DataRow newSnapshot = (DataRow) snapshots.get(i);
+                DataRow newSnapshot = snapshots.get(i);
 
                 if (cachedSnapshot != null) {
                     // use old snapshot if no changes occurred
                     if (object instanceof DataObject
                             && cachedSnapshot.equals(newSnapshot)) {
-                        ((DataObject) object).setSnapshotVersion(cachedSnapshot
-                                .getVersion());
+                        ((DataObject) object).setSnapshotVersion(cachedSnapshot.getVersion());
                         continue;
                     } else {
                         newSnapshot.setReplacesVersion(cachedSnapshot.getVersion());
@@ -228,7 +224,7 @@ public class DataRowStore implements Serializable {
                 }
 
                 if (modified == null) {
-                    modified = new HashMap();
+                    modified = new HashMap<>();
                     eventPostedBy = object.getObjectContext().getGraphManager();
                 }
 
@@ -240,9 +236,9 @@ public class DataRowStore implements Serializable {
             processSnapshotChanges(
                     eventPostedBy,
                     modified,
-                    Collections.EMPTY_LIST,
-                    Collections.EMPTY_LIST,
-                    Collections.EMPTY_LIST);
+                    Collections.<ObjectId>emptyList(),
+                    Collections.<ObjectId>emptyList(),
+                    Collections.<ObjectId>emptyList());
         }
     }
 
@@ -348,10 +344,10 @@ public class DataRowStore implements Serializable {
             logger.debug("remote event: " + event);
         }
 
-        Collection deletedSnapshotIds = event.getDeletedIds();
-        Collection invalidatedSnapshotIds = event.getInvalidatedIds();
-        Map diffs = event.getModifiedDiffs();
-        Collection indirectlyModifiedIds = event.getIndirectlyModifiedIds();
+        Collection<ObjectId> deletedSnapshotIds = event.getDeletedIds();
+        Collection<ObjectId> invalidatedSnapshotIds = event.getInvalidatedIds();
+        Map<ObjectId, DataRow> diffs = event.getModifiedDiffs();
+        Collection<ObjectId> indirectlyModifiedIds = event.getIndirectlyModifiedIds();
 
         if (deletedSnapshotIds.isEmpty()
                 && invalidatedSnapshotIds.isEmpty()
@@ -378,10 +374,10 @@ public class DataRowStore implements Serializable {
      */
     public void processSnapshotChanges(
             Object postedBy,
-            Map updatedSnapshots,
-            Collection deletedSnapshotIds,
-            Collection invalidatedSnapshotIds,
-            Collection indirectlyModifiedIds) {
+            Map<ObjectId, DataRow> updatedSnapshots,
+            Collection<ObjectId> deletedSnapshotIds,
+            Collection<ObjectId> invalidatedSnapshotIds,
+            Collection<ObjectId> indirectlyModifiedIds) {
 
         // update the internal cache, prepare snapshot event
 
@@ -395,7 +391,7 @@ public class DataRowStore implements Serializable {
 
         processDeletedIDs(deletedSnapshotIds);
         processInvalidatedIDs(invalidatedSnapshotIds);
-        Map diffs = processUpdatedSnapshots(updatedSnapshots);
+        Map<ObjectId, DataRow> diffs = processUpdatedSnapshots(updatedSnapshots);
         sendUpdateNotification(
                 postedBy,
                 diffs,
@@ -404,37 +400,32 @@ public class DataRowStore implements Serializable {
                 indirectlyModifiedIds);
     }
 
-    private void processDeletedIDs(Collection deletedSnapshotIDs) {
+    private void processDeletedIDs(Collection<ObjectId> deletedSnapshotIDs) {
         // DELETED: evict deleted snapshots
         if (!deletedSnapshotIDs.isEmpty()) {
-            Iterator it = deletedSnapshotIDs.iterator();
-            while (it.hasNext()) {
-                snapshots.remove(it.next());
+            for (ObjectId deletedSnapshotID : deletedSnapshotIDs) {
+                snapshots.remove(deletedSnapshotID);
             }
         }
     }
 
-    private void processInvalidatedIDs(Collection invalidatedSnapshotIds) {
+    private void processInvalidatedIDs(Collection<ObjectId> invalidatedSnapshotIds) {
         // INVALIDATED: forget snapshot, treat as expired from cache
         if (!invalidatedSnapshotIds.isEmpty()) {
-            Iterator it = invalidatedSnapshotIds.iterator();
-            while (it.hasNext()) {
-                snapshots.remove(it.next());
+            for (ObjectId invalidatedSnapshotId : invalidatedSnapshotIds) {
+                snapshots.remove(invalidatedSnapshotId);
             }
         }
     }
 
-    private Map processUpdatedSnapshots(Map updatedSnapshots) {
-        Map diffs = null;
+    private Map<ObjectId, DataRow> processUpdatedSnapshots(Map<ObjectId, DataRow> updatedSnapshots) {
+        Map<ObjectId, DataRow> diffs = null;
 
         // MODIFIED: replace/add snapshots, generate diffs for event
         if (!updatedSnapshots.isEmpty()) {
-            Iterator it = updatedSnapshots.entrySet().iterator();
-            while (it.hasNext()) {
-                Map.Entry entry = (Map.Entry) it.next();
-
-                ObjectId key = (ObjectId) entry.getKey();
-                DataRow newSnapshot = (DataRow) entry.getValue();
+            for (Map.Entry<ObjectId, DataRow> entry : updatedSnapshots.entrySet()) {
+                ObjectId key = entry.getKey();
+                DataRow newSnapshot = entry.getValue();
                 DataRow oldSnapshot = snapshots.put(key, newSnapshot);
 
                 // generate diff for the updated event, if this not a new
@@ -474,11 +465,11 @@ public class DataRowStore implements Serializable {
                         continue;
                     }
 
-                    Map diff = oldSnapshot.createDiff(newSnapshot);
+                    DataRow diff = oldSnapshot.createDiff(newSnapshot);
 
                     if (diff != null) {
                         if (diffs == null) {
-                            diffs = new HashMap();
+                            diffs = new HashMap<>();
                         }
 
                         diffs.put(key, diff);
@@ -490,20 +481,18 @@ public class DataRowStore implements Serializable {
         return diffs;
     }
 
-    private void processUpdateDiffs(Map diffs) {
+    private void processUpdateDiffs(Map<ObjectId, DataRow> diffs) {
         // apply snapshot diffs
         if (!diffs.isEmpty()) {
-            Iterator it = diffs.entrySet().iterator();
-            while (it.hasNext()) {
-                Map.Entry entry = (Map.Entry) it.next();
-                ObjectId key = (ObjectId) entry.getKey();
+            for (Map.Entry<ObjectId, DataRow> entry : diffs.entrySet()) {
+                ObjectId key = entry.getKey();
                 DataRow oldSnapshot = snapshots.remove(key);
 
                 if (oldSnapshot == null) {
                     continue;
                 }
 
-                DataRow newSnapshot = oldSnapshot.applyDiff((DataRow) entry.getValue());
+                DataRow newSnapshot = oldSnapshot.applyDiff(entry.getValue());
                 snapshots.put(key, newSnapshot);
             }
         }
@@ -511,10 +500,10 @@ public class DataRowStore implements Serializable {
 
     private void sendUpdateNotification(
             Object postedBy,
-            Map diffs,
-            Collection deletedSnapshotIDs,
-            Collection invalidatedSnapshotIDs,
-            Collection indirectlyModifiedIds) {
+            Map<ObjectId, DataRow> diffs,
+            Collection<ObjectId> deletedSnapshotIDs,
+            Collection<ObjectId> invalidatedSnapshotIDs,
+            Collection<ObjectId> indirectlyModifiedIds) {
 
         // do not send bogus events... e.g. inserted objects are not counted
         if ((diffs != null && !diffs.isEmpty())

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
index a3397b3..787c177 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java
@@ -23,9 +23,9 @@ import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.di.DIRuntimeException;
 import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.event.EventBridge;
 import org.apache.cayenne.event.EventManager;
+import org.apache.cayenne.event.NoopEventBridge;
 
 import java.util.Map;
 
@@ -36,30 +36,39 @@ import java.util.Map;
  */
 public class DefaultDataRowStoreFactory implements DataRowStoreFactory {
 
-    @Inject
-    protected Injector injector;
+    EventBridge eventBridge;
 
-    @Inject
-    protected EventManager eventManager;
+    EventManager eventManager;
 
-    @Inject(Constants.DATA_ROW_STORE_PROPERTIES_MAP)
     Map<String, String> properties;
 
+    boolean isNoopEventBridge;
+
+    public DefaultDataRowStoreFactory(@Inject EventBridge eventBridge,
+                                      @Inject EventManager eventManager,
+                                      @Inject(Constants.DATA_ROW_STORE_PROPERTIES_MAP) Map<String, String> properties) {
+        this.eventBridge = eventBridge;
+        this.eventManager = eventManager;
+        this.properties = properties;
+        isNoopEventBridge = eventBridge instanceof NoopEventBridge;
+    }
+
     @Override
     public DataRowStore createDataRowStore(String name) throws DIRuntimeException {
-        DataRowStore store = new DataRowStore(
-                name,
-                properties,
-                eventManager);
+        DataRowStore store = new DataRowStore(name, properties, eventManager);
+        setUpEventBridge(store);
+        return store;
+    }
 
+    private void setUpEventBridge(DataRowStore store) {
+        if(isNoopEventBridge) {
+            return;
+        }
         try {
-            store.setEventBridge(injector.getInstance(EventBridge.class));
+            store.setEventBridge(eventBridge);
             store.startListeners();
         } catch (Exception ex) {
             throw new CayenneRuntimeException("Error initializing DataRowStore.", ex);
         }
-
-        return store;
     }
-
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java b/cayenne-server/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java
index 613c88d..d75f232 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java
@@ -209,7 +209,7 @@ class HierarchicalObjectResolver {
 
             PrefetchTreeNode jointSubtree = node.cloneJointSubtree();
 
-            List dataRows = new ArrayList();
+            List<DataRow> dataRows = new ArrayList<>();
             for (PrefetchSelectQuery query : queries) {
                 // need to pass the remaining tree to make joint prefetches work
                 if (jointSubtree.hasChildren()) {
@@ -223,7 +223,7 @@ class HierarchicalObjectResolver {
                     query.addResultPath("db:"
                             + relationship.getReverseDbRelationshipPath());
                 }
-                dataRows.addAll(context.performQuery(query));
+                dataRows.addAll((List<DataRow>)context.performQuery(query));
             }
             processorNode.setDataRows(dataRows);
 
@@ -280,16 +280,16 @@ class HierarchicalObjectResolver {
                     return false;
                 }
 
-                List parentObjects = parent.getObjects();
+                List<Persistent> parentObjects = parent.getObjects();
                 int size = parentRows.size();
 
                 for (int i = 0; i < size; i++) {
                     subprocessor.setCurrentFlatRow((DataRow) parentRows.get(i));
-                    parent.setLastResolved((Persistent) parentObjects.get(i));
+                    parent.setLastResolved(parentObjects.get(i));
                     processorNode.traverse(subprocessor);
                 }
 
-                List objects = processorNode.getObjects();
+                List<Persistent> objects = processorNode.getObjects();
 
                 cache.snapshotsUpdatedForObjects(
                         objects,

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/access/PrefetchProcessorNode.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/PrefetchProcessorNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/PrefetchProcessorNode.java
index 09ce0fa..1fcb363 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/PrefetchProcessorNode.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/PrefetchProcessorNode.java
@@ -37,13 +37,13 @@ import org.apache.cayenne.util.ToStringBuilder;
  */
 class PrefetchProcessorNode extends PrefetchTreeNode {
 
-    List dataRows;
+    List<DataRow> dataRows;
     List<Persistent> objects;
 
     ArcProperty incoming;
     ObjectResolver resolver;
 
-    Map partitionByParent;
+    Map<Persistent, List<Persistent>> partitionByParent;
     boolean jointChildren;
 
     private Persistent lastResolved;
@@ -58,9 +58,8 @@ class PrefetchProcessorNode extends PrefetchTreeNode {
      * all properties are initialized.
      */
     void afterInit() {
-
         if (isPartitionedByParent()) {
-            partitionByParent = new HashMap();
+            partitionByParent = new HashMap<>();
         }
     }
 
@@ -76,21 +75,18 @@ class PrefetchProcessorNode extends PrefetchTreeNode {
             // away.... write directly to prevent changing persistence state.
             if (incoming instanceof ToOneProperty) {
                 incoming.writePropertyDirectly(parent, null, object);
-            }
-            else {
-
-                List peers = (List) partitionByParent.get(parent);
+            } else {
+                List<Persistent> peers = partitionByParent.get(parent);
 
                 // wrap in a list even if relationship is to-one... will unwrap at the end
                 // of the processing cycle.
                 if (peers == null) {
-                    peers = new ArrayList();
+                    peers = new ArrayList<>();
                     partitionByParent.put(parent, peers);
-                }
-                // checking for duplicates is needed in case of nested joint prefetches
-                // when there is more than one row with the same combination of adjacent
-                // parent and child...
-                else if (peers.contains(object)) {
+                } else if (peers.contains(object)) {
+                    // checking for duplicates is needed in case of nested joint prefetches
+                    // when there is more than one row with the same combination of adjacent
+                    // parent and child...
                     return;
                 }
 
@@ -108,17 +104,14 @@ class PrefetchProcessorNode extends PrefetchTreeNode {
             // use different strategy
 
             PrefetchProcessorNode parent = (PrefetchProcessorNode) getParent();
-            boolean parentObjectsExist = parent.getObjects() != null
-                    && parent.getObjects().size() > 0;
+            boolean parentObjectsExist = parent.getObjects() != null && parent.getObjects().size() > 0;
             if (incoming.getRelationship().isToMany()) {
                 if (parentObjectsExist) {
                     connectToNodeParents(parent.getObjects());
-                }
-                else {
+                } else {
                     connectToFaultedParents();
                 }
-            }
-            else {
+            } else {
                 // optional to-one ... need to fill in unresolved relationships with
                 // null...
                 if (parentObjectsExist) {
@@ -128,49 +121,40 @@ class PrefetchProcessorNode extends PrefetchTreeNode {
         }
     }
 
-    private void clearNullRelationships(List parentObjects) {
-        for (Object object : parentObjects) {
+    private void clearNullRelationships(List<Persistent> parentObjects) {
+        for (Persistent object : parentObjects) {
             if (incoming.readPropertyDirectly(object) instanceof Fault) {
                 incoming.writePropertyDirectly(object, null, null);
             }
         }
     }
 
-    private void connectToNodeParents(List parentObjects) {
-
-        for (Object parentObject : parentObjects) {
-            Persistent object = (Persistent) parentObject;
-            List related = (List) partitionByParent.get(object);
-            connect(object, related);
+    private void connectToNodeParents(List<Persistent> parentObjects) {
+        for (Persistent parentObject : parentObjects) {
+            connect(parentObject, partitionByParent.get(parentObject));
         }
     }
 
     private void connectToFaultedParents() {
-        for (Object o : partitionByParent.entrySet()) {
-            Map.Entry entry = (Map.Entry) o;
-
-            Persistent object = (Persistent) entry.getKey();
-            List related = (List) entry.getValue();
-            connect(object, related);
+        for (Map.Entry<Persistent, List<Persistent>> entry : partitionByParent.entrySet()) {
+            connect(entry.getKey(), entry.getValue());
         }
     }
 
-    private void connect(Persistent object, List related) {
+    private void connect(Persistent object, List<Persistent> related) {
         if (incoming.getRelationship().isToMany()) {
             ValueHolder toManyList = (ValueHolder) incoming.readProperty(object);
 
             // TODO, Andrus 11/15/2005 - if list is modified, shouldn't we attempt to
             // merge the changes instead of overwriting?
             toManyList.setValueDirectly(related != null ? related : new ArrayList(1));
-        }
-        else {
+        } else {
             // this should've been handled elsewhere
-            throw new CayenneRuntimeException(
-                    "To-one relationship wasn't handled properly: " + incoming.getName());
+            throw new CayenneRuntimeException("To-one relationship wasn't handled properly: %s", incoming.getName());
         }
     }
 
-    List getDataRows() {
+    List<DataRow> getDataRows() {
         return dataRows;
     }
 
@@ -194,7 +178,7 @@ class PrefetchProcessorNode extends PrefetchTreeNode {
         this.incoming = incoming;
     }
 
-    void setDataRows(List dataRows) {
+    void setDataRows(List<DataRow> dataRows) {
         this.dataRows = dataRows;
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/access/event/SnapshotEvent.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/event/SnapshotEvent.java b/cayenne-server/src/main/java/org/apache/cayenne/access/event/SnapshotEvent.java
index 61c2564..72bfb4b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/event/SnapshotEvent.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/event/SnapshotEvent.java
@@ -23,6 +23,8 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 
+import org.apache.cayenne.DataRow;
+import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.event.CayenneEvent;
 
 /**
@@ -33,14 +35,14 @@ import org.apache.cayenne.event.CayenneEvent;
 public class SnapshotEvent extends CayenneEvent {
 
     protected long timestamp;
-    protected Collection deletedIds;
-    protected Collection invalidatedIds;
-    protected Map modifiedDiffs;
-    protected Collection indirectlyModifiedIds;
+    protected Collection<ObjectId> deletedIds;
+    protected Collection<ObjectId> invalidatedIds;
+    protected Map<ObjectId, DataRow> modifiedDiffs;
+    protected Collection<ObjectId> indirectlyModifiedIds;
 
-    public SnapshotEvent(Object source, Object postedBy, Map modifiedDiffs,
-            Collection deletedIds, Collection invalidatedIds,
-            Collection indirectlyModifiedIds) {
+    public SnapshotEvent(Object source, Object postedBy, Map<ObjectId, DataRow> modifiedDiffs,
+            Collection<ObjectId> deletedIds, Collection<ObjectId> invalidatedIds,
+            Collection<ObjectId> indirectlyModifiedIds) {
 
         super(source, postedBy, null);
 
@@ -55,22 +57,22 @@ public class SnapshotEvent extends CayenneEvent {
         return timestamp;
     }
 
-    public Map getModifiedDiffs() {
-        return (modifiedDiffs != null) ? modifiedDiffs : Collections.EMPTY_MAP;
+    public Map<ObjectId, DataRow> getModifiedDiffs() {
+        return (modifiedDiffs != null) ? modifiedDiffs : Collections.<ObjectId, DataRow>emptyMap();
     }
 
-    public Collection getDeletedIds() {
-        return (deletedIds != null) ? deletedIds : Collections.EMPTY_LIST;
+    public Collection<ObjectId> getDeletedIds() {
+        return (deletedIds != null) ? deletedIds : Collections.<ObjectId>emptyList();
     }
 
-    public Collection getInvalidatedIds() {
-        return (invalidatedIds != null) ? invalidatedIds : Collections.EMPTY_LIST;
+    public Collection<ObjectId> getInvalidatedIds() {
+        return (invalidatedIds != null) ? invalidatedIds : Collections.<ObjectId>emptyList();
     }
 
-    public Collection getIndirectlyModifiedIds() {
+    public Collection<ObjectId> getIndirectlyModifiedIds() {
         return (indirectlyModifiedIds != null)
                 ? indirectlyModifiedIds
-                : Collections.EMPTY_LIST;
+                : Collections.<ObjectId>emptyList();
     }
 
     @Override
@@ -78,22 +80,22 @@ public class SnapshotEvent extends CayenneEvent {
         StringBuilder buffer = new StringBuilder();
         buffer.append("[SnapshotEvent] source: ").append(getSource());
 
-        Map modified = getModifiedDiffs();
+        Map<ObjectId, DataRow> modified = getModifiedDiffs();
         if (!modified.isEmpty()) {
             buffer.append(", modified ").append(modified.size()).append(" id(s)");
         }
 
-        Collection deleted = getDeletedIds();
+        Collection<ObjectId> deleted = getDeletedIds();
         if (!deleted.isEmpty()) {
             buffer.append(", deleted ").append(deleted.size()).append(" id(s)");
         }
 
-        Collection invalidated = getInvalidatedIds();
+        Collection<ObjectId> invalidated = getInvalidatedIds();
         if (!invalidated.isEmpty()) {
             buffer.append(", invalidated ").append(invalidated.size()).append(" id(s)");
         }
 
-        Collection related = getIndirectlyModifiedIds();
+        Collection<ObjectId> related = getIndirectlyModifiedIds();
         if (!related.isEmpty()) {
             buffer.append(", indirectly modified ").append(related.size()).append(
                     " id(s)");

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/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 8e24e38..5a4bf66 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
@@ -43,6 +43,8 @@ import org.apache.cayenne.access.types.CalendarType;
 import org.apache.cayenne.access.types.CharType;
 import org.apache.cayenne.access.types.DateType;
 import org.apache.cayenne.access.types.DoubleType;
+import org.apache.cayenne.access.types.ExtendedType;
+import org.apache.cayenne.access.types.ExtendedTypeFactory;
 import org.apache.cayenne.access.types.FloatType;
 import org.apache.cayenne.access.types.IntegerType;
 import org.apache.cayenne.access.types.LongType;
@@ -88,11 +90,12 @@ import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.ClassLoaderManager;
 import org.apache.cayenne.di.Key;
 import org.apache.cayenne.di.ListBuilder;
+import org.apache.cayenne.di.MapBuilder;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
 import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
 import org.apache.cayenne.event.DefaultEventManager;
-import org.apache.cayenne.event.EventBridgeProvider;
+import org.apache.cayenne.event.NoopEventBridgeProvider;
 import org.apache.cayenne.event.EventBridge;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.log.CommonsJdbcEventLogger;
@@ -294,7 +297,10 @@ public class ServerModule implements Module {
 
         binder.bind(QueryCache.class).toProvider(MapQueryCacheProvider.class);
 
-        binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+        binder.bind(EventBridge.class).toProvider(NoopEventBridgeProvider.class);
+
+        binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
+
         binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
 
 		// a service to provide the main stack DataDomain

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java
deleted file mode 100644
index ef78fb7..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java
+++ /dev/null
@@ -1,60 +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.event;
-
-import org.apache.cayenne.access.DataDomain;
-import org.apache.cayenne.access.DataRowStore;
-import org.apache.cayenne.di.DIRuntimeException;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.di.Provider;
-
-import java.util.Collections;
-
-public class EventBridgeProvider implements Provider<EventBridge> {
-
-    @Inject
-    protected DataDomain dataDomain;
-
-    @Override
-    public EventBridge get() throws DIRuntimeException {
-        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class.getClass(), dataDomain.getName());
-
-        return new EventBridge(
-                Collections.singleton(snapshotEventSubject),
-                EventBridge.convertToExternalSubject(snapshotEventSubject)) {
-
-            @Override
-            protected void startupExternal() throws Exception {
-
-            }
-
-            @Override
-            protected void shutdownExternal() throws Exception {
-
-            }
-
-            @Override
-            protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
-
-            }
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
index 217c5b3..fbd5468 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
@@ -39,7 +39,7 @@ public class JMSBridgeProvider implements Provider<EventBridge> {
 
     @Override
     public EventBridge get() throws DIRuntimeException {
-        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class, dataDomain.getName());;
+        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class, dataDomain.getName());
 
         return new JMSBridge(
                 Collections.singleton(snapshotEventSubject),

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
index 191872d..c2e184f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
@@ -39,7 +39,7 @@ public class JavaGroupsBridgeProvider implements Provider<EventBridge> {
 
     @Override
     public EventBridge get() throws DIRuntimeException {
-        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class, dataDomain.getName());;
+        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class, dataDomain.getName());
 
         return new JavaGroupsBridge(
                 Collections.singleton(snapshotEventSubject),

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/event/NoopEventBridge.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/NoopEventBridge.java b/cayenne-server/src/main/java/org/apache/cayenne/event/NoopEventBridge.java
new file mode 100644
index 0000000..5a4f941
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/NoopEventBridge.java
@@ -0,0 +1,43 @@
+/*****************************************************************
+ *   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.event;
+
+import org.apache.cayenne.access.DataRowStore;
+
+/**
+ * @since 4.0
+ */
+public class NoopEventBridge extends EventBridge {
+    NoopEventBridge() {
+        super(EventSubject.getSubject(DataRowStore.class, "noop-subject"), "noop-subject");
+    }
+
+    @Override
+    protected void startupExternal() throws Exception {
+    }
+
+    @Override
+    protected void shutdownExternal() throws Exception {
+    }
+
+    @Override
+    protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/event/NoopEventBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/NoopEventBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/NoopEventBridgeProvider.java
new file mode 100644
index 0000000..432b143
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/NoopEventBridgeProvider.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.event;
+
+import org.apache.cayenne.di.DIRuntimeException;
+import org.apache.cayenne.di.Provider;
+
+/**
+ * @since 4.0
+ */
+public class NoopEventBridgeProvider implements Provider<EventBridge> {
+
+    @Override
+    public EventBridge get() throws DIRuntimeException {
+        return new NoopEventBridge();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
index ae577f2..2870edf 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
@@ -39,7 +39,7 @@ public class XMPPBridgeProvider implements Provider<EventBridge> {
 
     @Override
     public EventBridge get() throws DIRuntimeException {
-        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class.getClass(), dataDomain.getName());;
+        EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class.getClass(), dataDomain.getName());
 
         return new XMPPBridge(
                 Collections.singleton(snapshotEventSubject),

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java
index 879e98d..889abd8 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java
@@ -59,7 +59,7 @@ public class DataRowStoreIT extends ServerCase {
     public void testDefaultConstructor() {
         cache = new DataRowStore(
                 "cacheXYZ",
-                Collections.EMPTY_MAP,
+                Collections.<String, String>emptyMap(),
                 null);
         assertEquals("cacheXYZ", cache.getName());
         assertNotNull(cache.getSnapshotEventSubject());
@@ -71,7 +71,7 @@ public class DataRowStoreIT extends ServerCase {
      */
     @Test
     public void testMaxSize() throws Exception {
-        Map<Object, Object> props = new HashMap<Object, Object>();
+        Map<String, String> props = new HashMap<>();
         props.put(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, String.valueOf(2));
 
         cache = new DataRowStore(
@@ -82,40 +82,40 @@ public class DataRowStoreIT extends ServerCase {
         assertEquals(0, cache.size());
 
         ObjectId key1 = new ObjectId("Artist", Artist.ARTIST_ID_PK_COLUMN, 1);
-        Map<Object, Object> diff1 = new HashMap<Object, Object>();
+        Map<ObjectId, DataRow> diff1 = new HashMap<>();
         diff1.put(key1, new DataRow(1));
 
         ObjectId key2 = new ObjectId("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
-        Map<Object, Object> diff2 = new HashMap<Object, Object>();
+        Map<ObjectId, DataRow> diff2 = new HashMap<>();
         diff2.put(key2, new DataRow(1));
 
         ObjectId key3 = new ObjectId("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
-        Map<Object, Object> diff3 = new HashMap<Object, Object>();
+        Map<ObjectId, DataRow> diff3 = new HashMap<>();
         diff3.put(key3, new DataRow(1));
 
         cache.processSnapshotChanges(
                 this,
                 diff1,
-                Collections.EMPTY_LIST,
-                Collections.EMPTY_LIST,
-                Collections.EMPTY_LIST);
+                Collections.<ObjectId>emptyList(),
+                Collections.<ObjectId>emptyList(),
+                Collections.<ObjectId>emptyList());
         assertEquals(1, cache.size());
 
         cache.processSnapshotChanges(
                 this,
                 diff2,
-                Collections.EMPTY_LIST,
-                Collections.EMPTY_LIST,
-                Collections.EMPTY_LIST);
+                Collections.<ObjectId>emptyList(),
+                Collections.<ObjectId>emptyList(),
+                Collections.<ObjectId>emptyList());
         assertEquals(2, cache.size());
 
         // this addition must overflow the cache, and throw out the first item
         cache.processSnapshotChanges(
                 this,
                 diff3,
-                Collections.EMPTY_LIST,
-                Collections.EMPTY_LIST,
-                Collections.EMPTY_LIST);
+                Collections.<ObjectId>emptyList(),
+                Collections.<ObjectId>emptyList(),
+                Collections.<ObjectId>emptyList());
         assertEquals(2, cache.size());
         assertNotNull(cache.getCachedSnapshot(key2));
         assertNotNull(cache.getCachedSnapshot(key3));

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java
index 2621443..779396a 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java
@@ -29,7 +29,7 @@ import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.event.DefaultEventManager;
 import org.apache.cayenne.event.EventBridge;
-import org.apache.cayenne.event.EventBridgeProvider;
+import org.apache.cayenne.event.NoopEventBridgeProvider;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.event.MockEventBridge;
 import org.apache.cayenne.event.MockEventBridgeProvider;
@@ -76,7 +76,7 @@ public class DefaultDataRowStoreFactoryIT extends ServerCase {
                 binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
                 binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);
                 binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
-                binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);
+                binder.bind(EventBridge.class).toProvider(NoopEventBridgeProvider.class);
                 binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
                 binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP)
                         .put(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, String.valueOf(CACHE_SIZE))

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/test/java/org/apache/cayenne/access/event/SnapshotEventTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/event/SnapshotEventTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/event/SnapshotEventTest.java
index 94a49e6..e24ce2e 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/event/SnapshotEventTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/event/SnapshotEventTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.cayenne.access.event;
 
+import org.apache.cayenne.DataRow;
+import org.apache.cayenne.ObjectId;
 import org.junit.Test;
 
 import java.util.ArrayList;
@@ -33,10 +35,10 @@ public class SnapshotEventTest {
     @Test
     public void testRootEvent() {
         Object source = new Object();
-        Collection<?> deleted = new ArrayList<Object>();
-        Collection<?> invalidated = new ArrayList<Object>();
-        Map<?, ?> modified = new HashMap<Object, Object>();
-        Collection<?> related = new ArrayList<Object>();
+        Collection<ObjectId> deleted = new ArrayList<>();
+        Collection<ObjectId> invalidated = new ArrayList<>();
+        Map<ObjectId, DataRow> modified = new HashMap<>();
+        Collection<ObjectId> related = new ArrayList<>();
 
         SnapshotEvent event = new SnapshotEvent(
                 source,

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
index 32477cb..f7a362d 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java
@@ -35,7 +35,7 @@ import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.DIBootstrap;
 import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.di.Module;
-import org.apache.cayenne.event.EventBridgeProvider;
+import org.apache.cayenne.event.NoopEventBridgeProvider;
 import org.apache.cayenne.event.EventBridge;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.event.MockEventManager;
@@ -80,7 +80,7 @@ public class DataContextFactoryTest {
                 binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
                 binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
                 binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
-                binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);
+                binder.bind(EventBridge.class).toProvider(NoopEventBridgeProvider.class);
                 binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
                 binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
             }
@@ -120,7 +120,7 @@ public class DataContextFactoryTest {
                 binder.bind(ObjectStoreFactory.class).to(DefaultObjectStoreFactory.class);
                 binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class);
                 binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
-                binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);
+                binder.bind(EventBridge.class).toProvider(NoopEventBridgeProvider.class);
                 binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
                 binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
             }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/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 54831de..7fe4763 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
@@ -73,7 +73,7 @@ import org.apache.cayenne.di.Module;
 import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
 import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
 import org.apache.cayenne.event.EventBridge;
-import org.apache.cayenne.event.EventBridgeProvider;
+import org.apache.cayenne.event.NoopEventBridgeProvider;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.event.MockEventManager;
 import org.apache.cayenne.log.CommonsJdbcEventLogger;
@@ -197,7 +197,7 @@ public class DataDomainProviderTest {
 				binder.bind(DataNodeFactory.class).to(DefaultDataNodeFactory.class);
 				binder.bind(SQLTemplateProcessor.class).toInstance(mock(SQLTemplateProcessor.class));
 
-                binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class);
+                binder.bind(EventBridge.class).toProvider(NoopEventBridgeProvider.class);
                 binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class);
                 binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP);
 			}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/982b1541/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java
index 7f225c8..a0efc04 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java
@@ -52,6 +52,7 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
 
     protected TextAdapter name;
     protected JCheckBox objectValidation;
+    protected JCheckBox sharedCache;
 
     public DataDomainView(ProjectController projectController) {
         this.projectController = projectController;
@@ -74,6 +75,7 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
         };
 
         this.objectValidation = new JCheckBox();
+        this.sharedCache = new JCheckBox();
 
         // assemble
         CellConstraints cc = new CellConstraints();
@@ -91,6 +93,9 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
         builder.addLabel("Object Validation:", cc.xy(1, 5));
         builder.add(objectValidation, cc.xy(3, 5));
 
+        builder.addLabel("Use Shared Cache:", cc.xy(1, 7));
+        builder.add(sharedCache, cc.xy(3, 7));
+
         this.setLayout(new BorderLayout());
         this.add(builder.getPanel(), BorderLayout.CENTER);
     }
@@ -110,6 +115,17 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
             }
         });
 
+        sharedCache.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                String value = sharedCache.isSelected() ? "true" : "false";
+                setDomainProperty(
+                        DataDomain.SHARED_CACHE_ENABLED_PROPERTY,
+                        value,
+                        Boolean.toString(DataDomain.SHARED_CACHE_ENABLED_DEFAULT));
+            }
+        });
+
     }
 
     /**
@@ -180,6 +196,10 @@ public class DataDomainView extends JPanel implements DomainDisplayListener {
         objectValidation.setSelected(getDomainBooleanProperty(
                 DataDomain.VALIDATING_OBJECTS_ON_COMMIT_PROPERTY,
                 Boolean.toString(DataDomain.VALIDATING_OBJECTS_ON_COMMIT_DEFAULT)));
+
+        sharedCache.setSelected(getDomainBooleanProperty(
+                DataDomain.SHARED_CACHE_ENABLED_PROPERTY,
+                Boolean.toString(DataDomain.SHARED_CACHE_ENABLED_DEFAULT)));
     }
 
     void setDomainName(String newName) {


[6/6] cayenne git commit: Merge branch 'CAY-1873-(2)' into asf-master

Posted by nt...@apache.org.
Merge branch 'CAY-1873-(2)' into asf-master


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

Branch: refs/heads/master
Commit: dfa3d87d88ee9c6eef07ec7db338f2154f86b416
Parents: 9c32b76 982b154
Author: Nikita Timofeev <st...@gmail.com>
Authored: Mon Mar 13 16:42:51 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Mon Mar 13 16:42:51 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/access/DataDomain.java   |  61 ++--
 .../org/apache/cayenne/access/DataRowStore.java | 215 ++++++------
 .../cayenne/access/DataRowStoreFactory.java     |  38 +++
 .../access/DefaultDataRowStoreFactory.java      |  74 ++++
 .../access/HierarchicalObjectResolver.java      |  10 +-
 .../cayenne/access/PrefetchProcessorNode.java   |  66 ++--
 .../cayenne/access/event/SnapshotEvent.java     |  40 +--
 .../apache/cayenne/configuration/Constants.java |  32 ++
 .../server/DataContextFactory.java              |  18 +-
 .../server/DataDomainProvider.java              |   2 +
 .../configuration/server/ServerModule.java      |  43 ++-
 .../cayenne/event/EventBridgeFactory.java       |   2 +-
 .../org/apache/cayenne/event/JMSBridge.java     |  35 +-
 .../apache/cayenne/event/JMSBridgeFactory.java  |  19 +-
 .../apache/cayenne/event/JMSBridgeProvider.java |  50 +++
 .../apache/cayenne/event/JavaGroupsBridge.java  |  33 +-
 .../cayenne/event/JavaGroupsBridgeFactory.java  | 109 +-----
 .../cayenne/event/JavaGroupsBridgeProvider.java |  50 +++
 .../apache/cayenne/event/NoopEventBridge.java   |  43 +++
 .../cayenne/event/NoopEventBridgeProvider.java  |  35 ++
 .../org/apache/cayenne/event/XMPPBridge.java    |  62 +++-
 .../apache/cayenne/event/XMPPBridgeFactory.java |  53 +--
 .../cayenne/event/XMPPBridgeProvider.java       |  50 +++
 .../apache/cayenne/access/DataRowStoreIT.java   |  60 +---
 .../access/DefaultDataRowStoreFactoryIT.java    | 123 +++++++
 .../apache/cayenne/access/MockDataRowStore.java |   7 +-
 .../cayenne/access/event/SnapshotEventTest.java |  10 +-
 .../server/DataContextFactoryTest.java          |  14 +
 .../server/DataDomainProviderTest.java          |   8 +
 .../cayenne/event/JGroupsBridgeFactoryTest.java |  46 ---
 .../cayenne/event/JMSBridgeFactoryTest.java     |  77 +++++
 .../cayenne/event/JMSBridgeProviderTest.java    | 119 +++++++
 .../event/JavaGroupsBridgeFactoryTest.java      |  84 +++++
 .../event/JavaGroupsBridgeProviderTest.java     | 123 +++++++
 .../cayenne/event/MockEventBridgeProvider.java  |  43 +++
 .../cayenne/event/XMPPBridgeFactoryTest.java    |  47 ++-
 .../cayenne/event/XMPPBridgeProviderTest.java   | 130 +++++++
 .../datadomain/CacheSyncConfigController.java   | 337 -------------------
 .../dialog/datadomain/CacheSyncConfigView.java  | 103 ------
 .../CustomRemoteEventsConfigPanel.java          |  58 ----
 .../dialog/datadomain/JGroupsConfigPanel.java   | 104 ------
 .../dialog/datadomain/JMSConfigPanel.java       |  58 ----
 .../cayenne/modeler/editor/DataDomainView.java  | 116 +------
 43 files changed, 1512 insertions(+), 1295 deletions(-)
----------------------------------------------------------------------