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 2018/02/05 09:29:35 UTC

[1/9] cayenne git commit: CAY-2403

Repository: cayenne
Updated Branches:
  refs/heads/master d8a944b0b -> 750d3d551


http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSModule.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSModule.java b/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSModule.java
deleted file mode 100644
index b532bc5..0000000
--- a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSModule.java
+++ /dev/null
@@ -1,54 +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.di.Binder;
-import org.apache.cayenne.di.MapBuilder;
-import org.apache.cayenne.di.Module;
-
-/**
- * @since 4.0
- */
-public class JMSModule implements Module {
-
-    /**
-     * A DI container key for the Map<String, String> storing
-     * {@link org.apache.cayenne.event.JMSBridge} properties
-     *
-     * @since 4.0
-     */
-    public static final String JMS_BRIDGE_PROPERTIES_MAP = "cayenne.server.jms_bridge";
-
-    public static void contributeTopicConnectionFactory(Binder binder, String factory) {
-        contributeProperties(binder).put(JMSBridge.TOPIC_CONNECTION_FACTORY_PROPERTY, factory);
-    }
-
-    private static MapBuilder<String> contributeProperties(Binder binder) {
-        return binder.bindMap(String.class, JMS_BRIDGE_PROPERTIES_MAP);
-    }
-
-    @Override
-    public void configure(Binder binder) {
-        // init properties' defaults
-        contributeTopicConnectionFactory(binder, JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT);
-
-        binder.bind(EventBridge.class).toProvider(JMSBridgeProvider.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSServerModuleProvider.java b/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSServerModuleProvider.java
deleted file mode 100644
index 6979d21..0000000
--- a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSServerModuleProvider.java
+++ /dev/null
@@ -1,50 +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 java.util.Collection;
-import java.util.Collections;
-
-import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
-import org.apache.cayenne.configuration.server.ServerModule;
-import org.apache.cayenne.di.Module;
-
-/**
- * @since 4.0
- */
-public class JMSServerModuleProvider implements CayenneServerModuleProvider {
-
-    @Override
-    public Module module() {
-        return new JMSModule();
-    }
-
-    @Override
-    public Class<? extends Module> moduleType() {
-        return JMSModule.class;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Collection<Class<? extends Module>> overrides() {
-        Collection modules = Collections.singletonList(ServerModule.class);
-        return modules;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/eventbridges/cayenne-jms/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
deleted file mode 100644
index 7c54e3f..0000000
--- a/eventbridges/cayenne-jms/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
+++ /dev/null
@@ -1,20 +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.
-##################################################################
-
-org.apache.cayenne.event.JMSServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/CayenneJMSModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/CayenneJMSModuleProviderTest.java b/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/CayenneJMSModuleProviderTest.java
deleted file mode 100644
index 3b3e87a..0000000
--- a/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/CayenneJMSModuleProviderTest.java
+++ /dev/null
@@ -1,36 +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.configuration.server.CayenneServerModuleProvider;
-import org.apache.cayenne.unit.util.ModuleProviderChecker;
-import org.junit.Test;
-
-/**
- * @since 4.0
- */
-public class CayenneJMSModuleProviderTest {
-
-    @Test
-    public void testAutoLoadable() {
-        ModuleProviderChecker.testProviderPresent(JMSServerModuleProvider.class, CayenneServerModuleProvider.class);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java b/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java
deleted file mode 100644
index 1e50145..0000000
--- a/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java
+++ /dev/null
@@ -1,77 +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 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.<String, String>emptyMap());
-
-        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<>();
-        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.<String, String>emptyMap());
-
-        assertEquals(bridge.getTopicConnectionFactoryName(), JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java b/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java
deleted file mode 100644
index 83404eb..0000000
--- a/eventbridges/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java
+++ /dev/null
@@ -1,87 +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.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.Slf4jJdbcEventLogger;
-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 {
-        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JMSModule());
-        EventBridge bridge = injector.getInstance(EventBridge.class);
-
-        assertNotNull(bridge);
-        assertTrue(bridge instanceof JMSBridge);
-    }
-
-    @Test
-    public void testUseProperties() {
-        Module module = binder -> JMSModule.contributeTopicConnectionFactory(binder, TOPIC_CONNECTION_FACTORY_TEST);
-
-        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JMSModule(), module);
-        JMSBridge bridge = (JMSBridge) injector.getInstance(EventBridge.class);
-
-        assertEquals(TOPIC_CONNECTION_FACTORY_TEST, bridge.getTopicConnectionFactoryName());
-    }
-
-    @Test
-    public void testUseDefaultProperties() throws Exception {
-        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JMSModule());
-        JMSBridge bridge = (JMSBridge) injector.getInstance(EventBridge.class);
-
-        assertEquals(JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT, bridge.getTopicConnectionFactoryName());
-    }
-
-    class DefaultBindings implements Module {
-        @Override
-        public void configure(Binder binder) {
-            binder.bindMap(String.class, 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(Slf4jJdbcEventLogger.class);
-            binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-xmpp/pom.xml
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/pom.xml b/eventbridges/cayenne-xmpp/pom.xml
deleted file mode 100644
index e57dc8f..0000000
--- a/eventbridges/cayenne-xmpp/pom.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  ~   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.
-  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>cayenne-eventbridges-parent</artifactId>
-        <groupId>org.apache.cayenne</groupId>
-        <version>4.1.M2-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>cayenne-xmpp</artifactId>
-    <name>cayenne-xmpp: Cayenne XMPP Event bridge</name>
-    <packaging>jar</packaging>
-
-    <dependencies>
-        <dependency>
-            <groupId>jivesoftware</groupId>
-            <artifactId>smack</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>jivesoftware</groupId>
-            <artifactId>smackx</artifactId>
-            <scope>provided</scope>
-        </dependency>
-    </dependencies>
-
-</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java b/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java
deleted file mode 100644
index d506d6c..0000000
--- a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java
+++ /dev/null
@@ -1,308 +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.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;
-import org.jivesoftware.smack.XMPPConnection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smack.packet.Packet;
-
-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.
- * What's good about XMPP (Extensible Messaging and Presence Protocol, an IETF standard
- * protocol that grew up from Jabber IM) is that generally it has fewer or no deployment
- * limitations (unlike JMS and JGroups that are generally a good solution for local
- * controlled networks). Also it provides lots of additional information for free, such as
- * presence, and much more.
- * <p>
- * This implementation is based on Smack XMPP client library from JiveSoftware.
- * </p>
- * 
- * @since 1.2
- */
-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;
-
-    protected boolean secureConnection;
-    protected String loginId;
-    protected String password;
-    protected String xmppHost;
-    protected int xmppPort;
-    protected String chatService;
-    protected String sessionHandle;
-
-    protected XMPPConnection connection;
-    protected GroupChat groupChat;
-    protected boolean connected;
-
-    /**
-     * Creates an XMPPBridge. External subject will be used as the chat group name.
-     */
-    public XMPPBridge(EventSubject localSubject, String externalSubject) {
-        this(Collections.singleton(localSubject), externalSubject);
-    }
-
-    /**
-     * Creates an XMPPBridge. External subject will be used as the chat group name.
-     */
-    public XMPPBridge(Collection<EventSubject> localSubjects, String externalSubject) {
-        super(localSubjects, externalSubject);
-
-        // generate a unique session handle... users can override it to use a specific
-        // handle...
-        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);
-        if (portString != null) {
-            try {
-                this.xmppPort = Integer.parseInt(portString);
-            } catch (NumberFormatException e) {
-                throw new CayenneRuntimeException("Invalid port: %s", portString);
-            }
-        }
-    }
-
-    public String getXmppHost() {
-        return xmppHost;
-    }
-
-    public void setXmppHost(String xmppHost) {
-        this.xmppHost = xmppHost;
-    }
-
-    public int getXmppPort() {
-        return xmppPort;
-    }
-
-    public void setXmppPort(int xmppPort) {
-        this.xmppPort = xmppPort;
-    }
-
-    public String getLoginId() {
-        return loginId;
-    }
-
-    public void setLoginId(String loginId) {
-        this.loginId = loginId;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-    public boolean isSecureConnection() {
-        return secureConnection;
-    }
-
-    public void setSecureConnection(boolean secureConnection) {
-        this.secureConnection = secureConnection;
-    }
-
-    public String getChatService() {
-        return chatService;
-    }
-
-    public void setChatService(String chatService) {
-        this.chatService = chatService;
-    }
-
-    public String getSessionHandle() {
-        return sessionHandle;
-    }
-
-    public void setSessionHandle(String sessionHandle) {
-        this.sessionHandle = sessionHandle;
-    }
-
-    @Override
-    protected void startupExternal() throws Exception {
-
-        // validate settings
-        if (xmppHost == null) {
-            throw new CayenneRuntimeException("Null 'xmppHost', can't start XMPPBridge");
-        }
-
-        // shutdown old bridge
-        if (connected) {
-            shutdownExternal();
-        }
-
-        try {
-            // connect and log in to chat
-            if (secureConnection) {
-                int port = xmppPort > 0 ? xmppPort : DEFAULT_XMPP_SECURE_PORT;
-                this.connection = new SSLXMPPConnection(xmppHost, port);
-            } else {
-                int port = xmppPort > 0 ? xmppPort : DEFAULT_XMPP_PORT;
-                this.connection = new XMPPConnection(xmppHost, port);
-            }
-
-            if (loginId != null) {
-                // it is important to provide a (pseudo) globally unique string as the
-                // third argument ("sessionHandle" is such string); without it same
-                // loginId can not be reused from the same machine.
-                connection.login(loginId, password, sessionHandle);
-            } else {
-                connection.loginAnonymously();
-            }
-        } catch (XMPPException e) {
-            throw new CayenneRuntimeException("Error connecting to XMPP Server: %s", e.getLocalizedMessage());
-        }
-
-        String service = chatService != null ? chatService : DEFAULT_CHAT_SERVICE;
-        try {
-            groupChat = connection.createGroupChat(externalSubject + '@' + service + "." + connection.getHost());
-            groupChat.join(sessionHandle);
-            groupChat.addMessageListener(new XMPPListener());
-        } catch (XMPPException e) {
-            throw new CayenneRuntimeException("Error setting up a group chat: %s", e.getLocalizedMessage());
-        }
-
-        this.connected = true;
-    }
-
-    @Override
-    protected void shutdownExternal() throws Exception {
-        if (groupChat != null) {
-            groupChat.leave();
-            groupChat = null;
-        }
-
-        if (connection != null) {
-            connection.close();
-            connection = null;
-        }
-
-        connected = false;
-    }
-
-    @Override
-    protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
-
-        Message message = groupChat.createMessage();
-        message.setBody(serializeToString(localEvent));
-
-        // set thread to our session handle to be able to discard messages from self
-        message.setThread(sessionHandle);
-
-        groupChat.sendMessage(message);
-    }
-
-    class XMPPListener implements PacketListener {
-
-        public void processPacket(Packet packet) {
-
-            if (packet instanceof Message) {
-                Message message = (Message) packet;
-
-                // filter our own messages
-                if (sessionHandle.equals(message.getThread())) {
-                    String payload = message.getBody();
-                    try {
-                        Object event = deserializeFromString(payload);
-                        if (event instanceof CayenneEvent) {
-                            onExternalEvent((CayenneEvent) event);
-                        }
-                    } catch (Exception ex) {
-                        // ignore for now... need to add logging.
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Decodes the String (assuming it is using Base64 encoding), and then deserializes
-     * object from the byte array.
-     */
-    static Object deserializeFromString(String string) throws Exception {
-        if (Util.isEmptyString(string)) {
-            return null;
-        }
-
-        byte[] bytes = Base64Codec.decodeBase64(string.getBytes());
-        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
-        Object object = in.readObject();
-        in.close();
-        return object;
-    }
-
-    /**
-     * Serializes object and then encodes it using Base64 encoding.
-     */
-    static String serializeToString(Object object) throws Exception {
-        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(bytes);
-        out.writeObject(object);
-        out.close();
-
-        return new String(Base64Codec.encodeBase64(bytes.toByteArray()));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java b/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
deleted file mode 100644
index 7934752..0000000
--- a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
+++ /dev/null
@@ -1,41 +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 java.util.Collection;
-import java.util.Map;
-
-/**
- * A factory of XMPPBridge. Note that to deploy an XMPPBridge, you need to have
- * <em>smack.jar</em> library in the runtime.
- * 
- * @since 1.2
- */
-public class XMPPBridgeFactory implements EventBridgeFactory {
-
-    @Override
-    public EventBridge createEventBridge(
-            Collection<EventSubject> localSubjects,
-            String externalSubject,
-            Map<String, String> properties) {
-        return new XMPPBridge(localSubjects, externalSubject, properties);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java b/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
deleted file mode 100644
index 38c9874..0000000
--- a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
+++ /dev/null
@@ -1,50 +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.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(XMPPModule.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/ab1fd0bf/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java b/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java
deleted file mode 100644
index 83c8f0a..0000000
--- a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java
+++ /dev/null
@@ -1,71 +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.di.Binder;
-import org.apache.cayenne.di.MapBuilder;
-import org.apache.cayenne.di.Module;
-
-/**
- * @since 4.0
- */
-public class XMPPModule implements Module {
-
-    /**
-     * 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";
-
-    public static void contributeHost(Binder binder, String host) {
-        contributeProperties(binder).put(XMPPBridge.XMPP_HOST_PROPERTY, host);
-    }
-
-    public static void contributePort(Binder binder, int port) {
-        contributeProperties(binder).put(XMPPBridge.XMPP_PORT_PROPERTY, Integer.toString(port));
-    }
-
-    public static void contributeLogin(Binder binder, String login, String password) {
-        contributeProperties(binder).put(XMPPBridge.XMPP_LOGIN_PROPERTY, login);
-        contributeProperties(binder).put(XMPPBridge.XMPP_PASSWORD_PROPERTY, password);
-    }
-
-    public static void contributeChatService(Binder binder, String chatService) {
-        contributeProperties(binder).put(XMPPBridge.XMPP_CHAT_SERVICE_PROPERTY, chatService);
-    }
-
-    public static void contributeSecureConnection(Binder binder, boolean secure) {
-        contributeProperties(binder).put(XMPPBridge.XMPP_SECURE_CONNECTION_PROPERTY, Boolean.toString(secure));
-    }
-
-    private static MapBuilder<String> contributeProperties(Binder binder) {
-        return binder.bindMap(String.class, XMPP_BRIDGE_PROPERTIES_MAP);
-    }
-
-    @Override
-    public void configure(Binder binder) {
-        // init properties' defaults
-        contributeChatService(binder, XMPPBridge.DEFAULT_CHAT_SERVICE);
-
-        binder.bind(EventBridge.class).toProvider(XMPPBridgeProvider.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java b/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java
deleted file mode 100644
index e8cf3da..0000000
--- a/eventbridges/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java
+++ /dev/null
@@ -1,50 +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 java.util.Collection;
-import java.util.Collections;
-
-import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
-import org.apache.cayenne.configuration.server.ServerModule;
-import org.apache.cayenne.di.Module;
-
-/**
- * @since 4.0
- */
-public class XMPPServerModuleProvider implements CayenneServerModuleProvider {
-
-    @Override
-    public Module module() {
-        return new XMPPModule();
-    }
-
-    @Override
-    public Class<? extends Module> moduleType() {
-        return XMPPModule.class;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Collection<Class<? extends Module>> overrides() {
-        Collection modules = Collections.singletonList(ServerModule.class);
-        return modules;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/eventbridges/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
deleted file mode 100644
index 00bce56..0000000
--- a/eventbridges/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
+++ /dev/null
@@ -1,20 +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.
-##################################################################
-
-org.apache.cayenne.event.XMPPServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java b/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java
deleted file mode 100644
index 0826f7c..0000000
--- a/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java
+++ /dev/null
@@ -1,36 +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.configuration.server.CayenneServerModuleProvider;
-import org.apache.cayenne.unit.util.ModuleProviderChecker;
-import org.junit.Test;
-
-/**
- * @since 4.0
- */
-public class CayenneXMPPModuleProviderTest {
-
-    @Test
-    public void testAutoLoadable() {
-        ModuleProviderChecker.testProviderPresent(XMPPServerModuleProvider.class, CayenneServerModuleProvider.class);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java b/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
deleted file mode 100644
index b5aa80a..0000000
--- a/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
+++ /dev/null
@@ -1,72 +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 java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-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() {
-        EventBridge bridge = new XMPPBridgeFactory().createEventBridge(
-                subjects,
-                externalSubject,
-                Collections.<String, String>emptyMap());
-
-        assertTrue(bridge instanceof XMPPBridge);
-        assertEquals(subjects, bridge.getLocalSubjects());
-        assertEquals(externalSubject, bridge.getExternalSubject());
-    }
-
-    @Test
-    public void testUseMapPropertiesSetter() throws Exception {
-        XMPPBridgeFactory bridgeFactory = new XMPPBridgeFactory();
-        Map<String, String> properties = new HashMap<>();
-
-        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(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/ab1fd0bf/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java b/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java
deleted file mode 100644
index f36d495..0000000
--- a/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java
+++ /dev/null
@@ -1,105 +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.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.Slf4jJdbcEventLogger;
-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 {
-        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new XMPPModule());
-        EventBridge bridge = injector.getInstance(EventBridge.class);
-
-        assertNotNull(bridge);
-        assertTrue(bridge instanceof XMPPBridge);
-    }
-
-    @Test
-    public void testUseProperties() throws Exception {
-        Module module = binder -> {
-            XMPPModule.contributeSecureConnection(binder, SECURE_CONNECTION_TEST);
-            XMPPModule.contributeHost(binder, HOST_TEST);
-            XMPPModule.contributePort(binder, PORT_TEST);
-            XMPPModule.contributeLogin(binder, LOGIN_TEST, PASSWORD_TEST);
-            XMPPModule.contributeChatService(binder, CHAT_SERVICE_TEST);
-        };
-
-        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new XMPPModule(), 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());
-    }
-
-    @Test
-    public void testUseDefaultProperties() throws Exception {
-        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new XMPPModule());
-        XMPPBridge bridge = (XMPPBridge) injector.getInstance(EventBridge.class);
-
-        assertEquals(XMPPBridge.DEFAULT_CHAT_SERVICE, bridge.getChatService());
-        assertEquals(0, bridge.getXmppPort());
-        assertEquals(false, bridge.isSecureConnection());
-    }
-
-    class DefaultBindings implements Module {
-        @Override
-        public void configure(Binder binder) {
-            binder.bindMap(String.class, 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(Slf4jJdbcEventLogger.class);
-            binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java b/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java
deleted file mode 100644
index 5422c3a..0000000
--- a/eventbridges/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java
+++ /dev/null
@@ -1,54 +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.HashMap;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- */
-public class XMPPBridgeTest {
-
-    @Test
-    public void testEventSerialization() throws Exception {
-        Map<String, String> info = new HashMap<>();
-        info.put("a", "b");
-        CayenneEvent e = new CayenneEvent(this, this, info);
-
-        String string = XMPPBridge.serializeToString(e);
-        assertNotNull(string);
-
-        Object copy = XMPPBridge.deserializeFromString(string);
-        assertNotNull(copy);
-        assertTrue(copy instanceof CayenneEvent);
-
-        CayenneEvent e2 = (CayenneEvent) copy;
-        assertEquals(info, e2.getInfo());
-        assertNull(e2.getPostedBy());
-        assertNull(e2.getSource());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/pom.xml
----------------------------------------------------------------------
diff --git a/eventbridges/pom.xml b/eventbridges/pom.xml
deleted file mode 100644
index 2c2d0f2..0000000
--- a/eventbridges/pom.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  ~   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.
-  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>cayenne-parent</artifactId>
-        <groupId>org.apache.cayenne</groupId>
-        <version>4.1.M2-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>cayenne-eventbridges-parent</artifactId>
-    <name>cayenne-eventbridges-parent: Event bridges implementations parent</name>
-    <packaging>pom</packaging>
-
-    <modules>
-        <module>cayenne-jgroups</module>
-        <module>cayenne-jms</module>
-        <module>cayenne-xmpp</module>
-    </modules>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.cayenne</groupId>
-            <artifactId>cayenne-server</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <!-- Test dependencies -->
-        <dependency>
-            <groupId>org.apache.cayenne</groupId>
-            <artifactId>cayenne-server</artifactId>
-            <version>${project.version}</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <!-- This ensures LICENSE and NOTICE inclusion in all jars -->
-            <plugin>
-                <artifactId>maven-remote-resources-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>process</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7444379..92435d9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,7 +74,9 @@
 		<module>cayenne-web</module>
 		<module>cayenne-osgi</module>
 		<module>cayenne-rop-server</module>
-		<module>eventbridges</module>
+		<module>cayenne-jgroups</module>
+		<module>cayenne-jms</module>
+		<module>cayenne-xmpp</module>
 		<module>itests</module>
 		<module>maven-plugins</module>
 		<module>modeler</module>


[2/9] cayenne git commit: CAY-2403

Posted by nt...@apache.org.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java
new file mode 100644
index 0000000..d506d6c
--- /dev/null
+++ b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java
@@ -0,0 +1,308 @@
+/*****************************************************************
+ *   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.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;
+import org.jivesoftware.smack.XMPPConnection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.Packet;
+
+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.
+ * What's good about XMPP (Extensible Messaging and Presence Protocol, an IETF standard
+ * protocol that grew up from Jabber IM) is that generally it has fewer or no deployment
+ * limitations (unlike JMS and JGroups that are generally a good solution for local
+ * controlled networks). Also it provides lots of additional information for free, such as
+ * presence, and much more.
+ * <p>
+ * This implementation is based on Smack XMPP client library from JiveSoftware.
+ * </p>
+ * 
+ * @since 1.2
+ */
+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;
+
+    protected boolean secureConnection;
+    protected String loginId;
+    protected String password;
+    protected String xmppHost;
+    protected int xmppPort;
+    protected String chatService;
+    protected String sessionHandle;
+
+    protected XMPPConnection connection;
+    protected GroupChat groupChat;
+    protected boolean connected;
+
+    /**
+     * Creates an XMPPBridge. External subject will be used as the chat group name.
+     */
+    public XMPPBridge(EventSubject localSubject, String externalSubject) {
+        this(Collections.singleton(localSubject), externalSubject);
+    }
+
+    /**
+     * Creates an XMPPBridge. External subject will be used as the chat group name.
+     */
+    public XMPPBridge(Collection<EventSubject> localSubjects, String externalSubject) {
+        super(localSubjects, externalSubject);
+
+        // generate a unique session handle... users can override it to use a specific
+        // handle...
+        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);
+        if (portString != null) {
+            try {
+                this.xmppPort = Integer.parseInt(portString);
+            } catch (NumberFormatException e) {
+                throw new CayenneRuntimeException("Invalid port: %s", portString);
+            }
+        }
+    }
+
+    public String getXmppHost() {
+        return xmppHost;
+    }
+
+    public void setXmppHost(String xmppHost) {
+        this.xmppHost = xmppHost;
+    }
+
+    public int getXmppPort() {
+        return xmppPort;
+    }
+
+    public void setXmppPort(int xmppPort) {
+        this.xmppPort = xmppPort;
+    }
+
+    public String getLoginId() {
+        return loginId;
+    }
+
+    public void setLoginId(String loginId) {
+        this.loginId = loginId;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public boolean isSecureConnection() {
+        return secureConnection;
+    }
+
+    public void setSecureConnection(boolean secureConnection) {
+        this.secureConnection = secureConnection;
+    }
+
+    public String getChatService() {
+        return chatService;
+    }
+
+    public void setChatService(String chatService) {
+        this.chatService = chatService;
+    }
+
+    public String getSessionHandle() {
+        return sessionHandle;
+    }
+
+    public void setSessionHandle(String sessionHandle) {
+        this.sessionHandle = sessionHandle;
+    }
+
+    @Override
+    protected void startupExternal() throws Exception {
+
+        // validate settings
+        if (xmppHost == null) {
+            throw new CayenneRuntimeException("Null 'xmppHost', can't start XMPPBridge");
+        }
+
+        // shutdown old bridge
+        if (connected) {
+            shutdownExternal();
+        }
+
+        try {
+            // connect and log in to chat
+            if (secureConnection) {
+                int port = xmppPort > 0 ? xmppPort : DEFAULT_XMPP_SECURE_PORT;
+                this.connection = new SSLXMPPConnection(xmppHost, port);
+            } else {
+                int port = xmppPort > 0 ? xmppPort : DEFAULT_XMPP_PORT;
+                this.connection = new XMPPConnection(xmppHost, port);
+            }
+
+            if (loginId != null) {
+                // it is important to provide a (pseudo) globally unique string as the
+                // third argument ("sessionHandle" is such string); without it same
+                // loginId can not be reused from the same machine.
+                connection.login(loginId, password, sessionHandle);
+            } else {
+                connection.loginAnonymously();
+            }
+        } catch (XMPPException e) {
+            throw new CayenneRuntimeException("Error connecting to XMPP Server: %s", e.getLocalizedMessage());
+        }
+
+        String service = chatService != null ? chatService : DEFAULT_CHAT_SERVICE;
+        try {
+            groupChat = connection.createGroupChat(externalSubject + '@' + service + "." + connection.getHost());
+            groupChat.join(sessionHandle);
+            groupChat.addMessageListener(new XMPPListener());
+        } catch (XMPPException e) {
+            throw new CayenneRuntimeException("Error setting up a group chat: %s", e.getLocalizedMessage());
+        }
+
+        this.connected = true;
+    }
+
+    @Override
+    protected void shutdownExternal() throws Exception {
+        if (groupChat != null) {
+            groupChat.leave();
+            groupChat = null;
+        }
+
+        if (connection != null) {
+            connection.close();
+            connection = null;
+        }
+
+        connected = false;
+    }
+
+    @Override
+    protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
+
+        Message message = groupChat.createMessage();
+        message.setBody(serializeToString(localEvent));
+
+        // set thread to our session handle to be able to discard messages from self
+        message.setThread(sessionHandle);
+
+        groupChat.sendMessage(message);
+    }
+
+    class XMPPListener implements PacketListener {
+
+        public void processPacket(Packet packet) {
+
+            if (packet instanceof Message) {
+                Message message = (Message) packet;
+
+                // filter our own messages
+                if (sessionHandle.equals(message.getThread())) {
+                    String payload = message.getBody();
+                    try {
+                        Object event = deserializeFromString(payload);
+                        if (event instanceof CayenneEvent) {
+                            onExternalEvent((CayenneEvent) event);
+                        }
+                    } catch (Exception ex) {
+                        // ignore for now... need to add logging.
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Decodes the String (assuming it is using Base64 encoding), and then deserializes
+     * object from the byte array.
+     */
+    static Object deserializeFromString(String string) throws Exception {
+        if (Util.isEmptyString(string)) {
+            return null;
+        }
+
+        byte[] bytes = Base64Codec.decodeBase64(string.getBytes());
+        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
+        Object object = in.readObject();
+        in.close();
+        return object;
+    }
+
+    /**
+     * Serializes object and then encodes it using Base64 encoding.
+     */
+    static String serializeToString(Object object) throws Exception {
+        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bytes);
+        out.writeObject(object);
+        out.close();
+
+        return new String(Base64Codec.encodeBase64(bytes.toByteArray()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
new file mode 100644
index 0000000..7934752
--- /dev/null
+++ b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java
@@ -0,0 +1,41 @@
+/*****************************************************************
+ *   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 java.util.Collection;
+import java.util.Map;
+
+/**
+ * A factory of XMPPBridge. Note that to deploy an XMPPBridge, you need to have
+ * <em>smack.jar</em> library in the runtime.
+ * 
+ * @since 1.2
+ */
+public class XMPPBridgeFactory implements EventBridgeFactory {
+
+    @Override
+    public EventBridge createEventBridge(
+            Collection<EventSubject> localSubjects,
+            String externalSubject,
+            Map<String, String> properties) {
+        return new XMPPBridge(localSubjects, externalSubject, properties);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java
new file mode 100644
index 0000000..38c9874
--- /dev/null
+++ b/cayenne-xmpp/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(XMPPModule.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/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java
new file mode 100644
index 0000000..83c8f0a
--- /dev/null
+++ b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java
@@ -0,0 +1,71 @@
+/*****************************************************************
+ *   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.Binder;
+import org.apache.cayenne.di.MapBuilder;
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.0
+ */
+public class XMPPModule implements Module {
+
+    /**
+     * 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";
+
+    public static void contributeHost(Binder binder, String host) {
+        contributeProperties(binder).put(XMPPBridge.XMPP_HOST_PROPERTY, host);
+    }
+
+    public static void contributePort(Binder binder, int port) {
+        contributeProperties(binder).put(XMPPBridge.XMPP_PORT_PROPERTY, Integer.toString(port));
+    }
+
+    public static void contributeLogin(Binder binder, String login, String password) {
+        contributeProperties(binder).put(XMPPBridge.XMPP_LOGIN_PROPERTY, login);
+        contributeProperties(binder).put(XMPPBridge.XMPP_PASSWORD_PROPERTY, password);
+    }
+
+    public static void contributeChatService(Binder binder, String chatService) {
+        contributeProperties(binder).put(XMPPBridge.XMPP_CHAT_SERVICE_PROPERTY, chatService);
+    }
+
+    public static void contributeSecureConnection(Binder binder, boolean secure) {
+        contributeProperties(binder).put(XMPPBridge.XMPP_SECURE_CONNECTION_PROPERTY, Boolean.toString(secure));
+    }
+
+    private static MapBuilder<String> contributeProperties(Binder binder) {
+        return binder.bindMap(String.class, XMPP_BRIDGE_PROPERTIES_MAP);
+    }
+
+    @Override
+    public void configure(Binder binder) {
+        // init properties' defaults
+        contributeChatService(binder, XMPPBridge.DEFAULT_CHAT_SERVICE);
+
+        binder.bind(EventBridge.class).toProvider(XMPPBridgeProvider.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java
new file mode 100644
index 0000000..e8cf3da
--- /dev/null
+++ b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.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 java.util.Collection;
+import java.util.Collections;
+
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.configuration.server.ServerModule;
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.0
+ */
+public class XMPPServerModuleProvider implements CayenneServerModuleProvider {
+
+    @Override
+    public Module module() {
+        return new XMPPModule();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return XMPPModule.class;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Collection<Class<? extends Module>> overrides() {
+        Collection modules = Collections.singletonList(ServerModule.class);
+        return modules;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
new file mode 100644
index 0000000..00bce56
--- /dev/null
+++ b/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+#   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.
+##################################################################
+
+org.apache.cayenne.event.XMPPServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java
new file mode 100644
index 0000000..0826f7c
--- /dev/null
+++ b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java
@@ -0,0 +1,36 @@
+/*****************************************************************
+ *   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.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.unit.util.ModuleProviderChecker;
+import org.junit.Test;
+
+/**
+ * @since 4.0
+ */
+public class CayenneXMPPModuleProviderTest {
+
+    @Test
+    public void testAutoLoadable() {
+        ModuleProviderChecker.testProviderPresent(XMPPServerModuleProvider.class, CayenneServerModuleProvider.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
new file mode 100644
index 0000000..b5aa80a
--- /dev/null
+++ b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java
@@ -0,0 +1,72 @@
+/*****************************************************************
+ *   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.assertTrue;
+
+public class XMPPBridgeFactoryTest {
+
+    protected Collection<EventSubject> subjects = Collections.singleton(new EventSubject("test"));
+    protected String externalSubject = "subject";
+
+    @Test
+    public void testCreateEventBridge() {
+        EventBridge bridge = new XMPPBridgeFactory().createEventBridge(
+                subjects,
+                externalSubject,
+                Collections.<String, String>emptyMap());
+
+        assertTrue(bridge instanceof XMPPBridge);
+        assertEquals(subjects, bridge.getLocalSubjects());
+        assertEquals(externalSubject, bridge.getExternalSubject());
+    }
+
+    @Test
+    public void testUseMapPropertiesSetter() throws Exception {
+        XMPPBridgeFactory bridgeFactory = new XMPPBridgeFactory();
+        Map<String, String> properties = new HashMap<>();
+
+        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(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/ab1fd0bf/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java
new file mode 100644
index 0000000..f36d495
--- /dev/null
+++ b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java
@@ -0,0 +1,105 @@
+/*****************************************************************
+ *   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.Slf4jJdbcEventLogger;
+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 {
+        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new XMPPModule());
+        EventBridge bridge = injector.getInstance(EventBridge.class);
+
+        assertNotNull(bridge);
+        assertTrue(bridge instanceof XMPPBridge);
+    }
+
+    @Test
+    public void testUseProperties() throws Exception {
+        Module module = binder -> {
+            XMPPModule.contributeSecureConnection(binder, SECURE_CONNECTION_TEST);
+            XMPPModule.contributeHost(binder, HOST_TEST);
+            XMPPModule.contributePort(binder, PORT_TEST);
+            XMPPModule.contributeLogin(binder, LOGIN_TEST, PASSWORD_TEST);
+            XMPPModule.contributeChatService(binder, CHAT_SERVICE_TEST);
+        };
+
+        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new XMPPModule(), 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());
+    }
+
+    @Test
+    public void testUseDefaultProperties() throws Exception {
+        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new XMPPModule());
+        XMPPBridge bridge = (XMPPBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(XMPPBridge.DEFAULT_CHAT_SERVICE, bridge.getChatService());
+        assertEquals(0, bridge.getXmppPort());
+        assertEquals(false, bridge.isSecureConnection());
+    }
+
+    class DefaultBindings implements Module {
+        @Override
+        public void configure(Binder binder) {
+            binder.bindMap(String.class, 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(Slf4jJdbcEventLogger.class);
+            binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java
new file mode 100644
index 0000000..5422c3a
--- /dev/null
+++ b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java
@@ -0,0 +1,54 @@
+/*****************************************************************
+ *   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.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ */
+public class XMPPBridgeTest {
+
+    @Test
+    public void testEventSerialization() throws Exception {
+        Map<String, String> info = new HashMap<>();
+        info.put("a", "b");
+        CayenneEvent e = new CayenneEvent(this, this, info);
+
+        String string = XMPPBridge.serializeToString(e);
+        assertNotNull(string);
+
+        Object copy = XMPPBridge.deserializeFromString(string);
+        assertNotNull(copy);
+        assertTrue(copy instanceof CayenneEvent);
+
+        CayenneEvent e2 = (CayenneEvent) copy;
+        assertEquals(info, e2.getInfo());
+        assertNull(e2.getPostedBy());
+        assertNull(e2.getSource());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/pom.xml
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/pom.xml b/eventbridges/cayenne-jgroups/pom.xml
deleted file mode 100644
index 3d0944e..0000000
--- a/eventbridges/cayenne-jgroups/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  ~   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.
-  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>cayenne-eventbridges-parent</artifactId>
-        <groupId>org.apache.cayenne</groupId>
-        <version>4.1.M2-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>cayenne-jgroups</artifactId>
-    <name>cayenne-jgroups: Cayenne JGroups Event bridge</name>
-    <packaging>jar</packaging>
-
-    <dependencies>
-        <dependency>
-            <groupId>jgroups</groupId>
-            <artifactId>jgroups-all</artifactId>
-            <scope>provided</scope>
-        </dependency>
-    </dependencies>
-
-</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java
deleted file mode 100644
index 77738c3..0000000
--- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java
+++ /dev/null
@@ -1,63 +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.di.Binder;
-import org.apache.cayenne.di.MapBuilder;
-import org.apache.cayenne.di.Module;
-
-/**
- * @since 4.0
- */
-public class JGroupsModule implements Module {
-
-    /**
-     * 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";
-
-    public static void contributeMulticastAddress(Binder binder, String address) {
-        contributeProperties(binder).put(JavaGroupsBridge.MCAST_ADDRESS_PROPERTY, address);
-    }
-
-    public static void contributeMulticastPort(Binder binder, int port) {
-        contributeProperties(binder).put(JavaGroupsBridge.MCAST_PORT_PROPERTY, Integer.toString(port));
-    }
-
-    public static void contributeConfigUrl(Binder binder, String config) {
-        contributeProperties(binder).put(JavaGroupsBridge.JGROUPS_CONFIG_URL_PROPERTY, config);
-    }
-
-    private static MapBuilder<String> contributeProperties(Binder binder) {
-        return binder.bindMap(String.class, JAVA_GROUPS_BRIDGE_PROPERTIES_MAP);
-    }
-
-    @Override
-    public void configure(Binder binder) {
-        // init properties' defaults
-        contributeMulticastAddress(binder, JavaGroupsBridge.MCAST_ADDRESS_DEFAULT);
-        contributeMulticastPort(binder, JavaGroupsBridge.MCAST_PORT_DEFAULT_INT);
-
-        binder.bind(EventBridge.class).toProvider(JavaGroupsBridgeProvider.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java
deleted file mode 100644
index 60c5bcd..0000000
--- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java
+++ /dev/null
@@ -1,50 +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 java.util.Collection;
-import java.util.Collections;
-
-import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
-import org.apache.cayenne.configuration.server.ServerModule;
-import org.apache.cayenne.di.Module;
-
-/**
- * @since 4.0
- */
-public class JGroupsServerModuleProvider implements CayenneServerModuleProvider {
-
-    @Override
-    public Module module() {
-        return new JGroupsModule();
-    }
-
-    @Override
-    public Class<? extends Module> moduleType() {
-        return JGroupsModule.class;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Collection<Class<? extends Module>> overrides() {
-        Collection modules = Collections.singletonList(ServerModule.class);
-        return modules;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
deleted file mode 100644
index cd7bae2..0000000
--- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
+++ /dev/null
@@ -1,231 +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.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.
- * 
- * @since 1.1
- */
-public class JavaGroupsBridge extends EventBridge implements MessageListener {
-
-    public static final String MCAST_ADDRESS_DEFAULT = "228.0.0.5";
-    public static final int MCAST_PORT_DEFAULT_INT = 22222;
-    public static final String MCAST_PORT_DEFAULT = Integer.toString(MCAST_PORT_DEFAULT_INT);
-
-    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;
-
-    protected Channel channel;
-    protected PullPushAdapter adapter;
-    protected String multicastAddress;
-    protected String multicastPort;
-    protected String configURL;
-
-    /**
-     * Creates new instance of JavaGroupsBridge.
-     */
-    public JavaGroupsBridge(EventSubject localSubject, String externalSubject) {
-        super(localSubject, externalSubject);
-    }
-
-    /**
-     * @since 1.2
-     */
-    public JavaGroupsBridge(Collection<EventSubject> localSubjects, String externalSubject) {
-        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;
-    }
-
-    public void setConfigURL(String configURL) {
-        this.configURL = configURL;
-    }
-
-    public String getMulticastAddress() {
-        return multicastAddress;
-    }
-
-    public void setMulticastAddress(String multicastAddress) {
-        this.multicastAddress = multicastAddress;
-    }
-
-    public String getMulticastPort() {
-        return multicastPort;
-    }
-
-    public void setMulticastPort(String multicastPort) {
-        this.multicastPort = multicastPort;
-    }
-
-    public byte[] getState() {
-        return state;
-    }
-
-    public void setState(byte[] state) {
-        this.state = state;
-    }
-
-    /**
-     * Implementation of org.javagroups.MessageListener - a callback method to process
-     * incoming messages.
-     */
-    public void receive(Message message) {
-        try {
-            CayenneEvent event = messageObjectToEvent((Serializable) message.getObject());
-            if (event != null) {
-
-                onExternalEvent(event);
-            }
-        }
-        catch (Exception ex) {
-            // TODO: Andrus, 2/8/2006 logging... Log4J was removed to make this usable on
-            // the client
-        }
-    }
-
-    @Override
-    protected void startupExternal() throws Exception {
-        // TODO: need to do more research to figure out the best default transport
-        // settings
-        // to avoid fragmentation, etc.
-
-        // if config file is set, use it, otherwise use a default
-        // set of properties, trying to configure multicast address and port
-        if (configURL != null) {
-            channel = new JChannel(configURL);
-        }
-        else {
-            String configString = buildConfigString();
-            channel = new JChannel(configString);
-        }
-
-        // Important - discard messages from self
-        channel.setOpt(Channel.LOCAL, Boolean.FALSE);
-        channel.connect(externalSubject);
-
-        if (receivesExternalEvents()) {
-            adapter = new PullPushAdapter(channel, this);
-        }
-    }
-
-    /**
-     * Creates JavaGroups configuration String, using preconfigured multicast port and
-     * address.
-     */
-    protected String buildConfigString() {
-        if (multicastAddress == null) {
-            throw new IllegalStateException("'multcastAddress' is not set");
-        }
-
-        if (multicastPort == null) {
-            throw new IllegalStateException("'multcastPort' is not set");
-        }
-
-        return "UDP(mcast_addr="
-                + multicastAddress
-                + ";mcast_port="
-                + multicastPort
-                + ";ip_ttl=32):"
-                + "PING(timeout=3000;num_initial_members=6):"
-                + "FD(timeout=3000):"
-                + "VERIFY_SUSPECT(timeout=1500):"
-                + "pbcast.NAKACK(gc_lag=10;retransmit_timeout=600,1200,2400,4800):"
-                + "pbcast.STABLE(desired_avg_gossip=10000):"
-                + "FRAG:"
-                + "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;"
-                + "shun=true;print_local_addr=false)";
-    }
-
-    @Override
-    protected void shutdownExternal() throws Exception {
-        try {
-            if (adapter != null) {
-                adapter.stop();
-            }
-
-            channel.close();
-        }
-        finally {
-            adapter = null;
-            channel = null;
-        }
-    }
-
-    @Override
-    protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
-        Message message = new Message(null, null, eventToMessageObject(localEvent));
-        channel.send(message);
-    }
-
-    /**
-     * Converts CayenneEvent to a serializable object that will be sent via JMS. Default
-     * implementation simply returns the event, but subclasses can customize this
-     * behavior.
-     */
-    protected Serializable eventToMessageObject(CayenneEvent event) throws Exception {
-        return event;
-    }
-
-    /**
-     * Converts a Serializable instance to CayenneEvent. Returns null if the object is not
-     * supported. Default implementation simply tries to cast the object to CayenneEvent,
-     * but subclasses can customize this behavior.
-     */
-    protected CayenneEvent messageObjectToEvent(Serializable object) throws Exception {
-        return (object instanceof CayenneEvent) ? (CayenneEvent) object : null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
deleted file mode 100644
index 302e5ca..0000000
--- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
+++ /dev/null
@@ -1,49 +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 java.util.Collection;
-import java.util.Map;
-
-/**
- * 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 {
-
-    /**
-     * Creates a JavaGroupsBridge instance. Since JavaGroups is not shipped with Cayenne
-     * and should be installed separately, a common misconfiguration problem may be the
-     * absence of JavaGroups jar file. This factory returns a dummy noop EventBridge, if
-     * this is the case. This would allow the application to continue to run, but without
-     * remote notifications.
-     */
-    public EventBridge createEventBridge(
-            Collection<EventSubject> localSubjects,
-            String externalSubject,
-            Map<String, String> properties) {
-        return new JavaGroupsBridge(localSubjects, externalSubject, properties);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
deleted file mode 100644
index 983aa7f..0000000
--- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
+++ /dev/null
@@ -1,50 +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.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(JGroupsModule.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/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/eventbridges/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
deleted file mode 100644
index b6c6632..0000000
--- a/eventbridges/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
+++ /dev/null
@@ -1,20 +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.
-##################################################################
-
-org.apache.cayenne.event.JGroupsServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java b/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java
deleted file mode 100644
index 320d490..0000000
--- a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java
+++ /dev/null
@@ -1,36 +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.configuration.server.CayenneServerModuleProvider;
-import org.apache.cayenne.unit.util.ModuleProviderChecker;
-import org.junit.Test;
-
-/**
- * @since 4.0
- */
-public class CayenneJGroupsModuleProviderTest {
-
-    @Test
-    public void testAutoLoadable() {
-        ModuleProviderChecker.testProviderPresent(JGroupsServerModuleProvider.class, CayenneServerModuleProvider.class);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java b/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java
deleted file mode 100644
index 694dc24..0000000
--- a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java
+++ /dev/null
@@ -1,84 +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 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.<String, String>emptyMap());
-
-        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<>();
-        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.<String, String>emptyMap());
-
-        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/ab1fd0bf/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java b/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java
deleted file mode 100644
index 00232d4..0000000
--- a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java
+++ /dev/null
@@ -1,97 +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.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.Slf4jJdbcEventLogger;
-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 {
-        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JGroupsModule());
-        EventBridge bridge = injector.getInstance(EventBridge.class);
-
-        assertNotNull(bridge);
-        assertTrue(bridge instanceof JavaGroupsBridge);
-    }
-
-    @Test
-    public void testUseProperties() throws Exception {
-        Module module = binder -> {
-            JGroupsModule.contributeMulticastAddress(binder, MCAST_ADDRESS_TEST);
-            JGroupsModule.contributeMulticastPort(binder, Integer.parseInt(MCAST_PORT_TEST));
-            JGroupsModule.contributeConfigUrl(binder, CONFIG_URL_TEST);
-        };
-
-        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JGroupsModule(), 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 {
-        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JGroupsModule());
-        JavaGroupsBridge bridge = (JavaGroupsBridge) injector.getInstance(EventBridge.class);
-
-        assertEquals(JavaGroupsBridge.MCAST_ADDRESS_DEFAULT, bridge.getMulticastAddress());
-        assertEquals(JavaGroupsBridge.MCAST_PORT_DEFAULT, bridge.getMulticastPort());
-        assertEquals(null, bridge.getConfigURL());
-    }
-
-    class DefaultBindings implements Module {
-        @Override
-        public void configure(Binder binder) {
-            binder.bindMap(String.class, 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(Slf4jJdbcEventLogger.class);
-            binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/pom.xml
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/pom.xml b/eventbridges/cayenne-jms/pom.xml
deleted file mode 100644
index 6ae9192..0000000
--- a/eventbridges/cayenne-jms/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  ~   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.
-  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>cayenne-eventbridges-parent</artifactId>
-        <groupId>org.apache.cayenne</groupId>
-        <version>4.1.M2-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>cayenne-jms</artifactId>
-    <name>cayenne-jms: Cayenne JMS Event bridge</name>
-    <packaging>jar</packaging>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.geronimo.specs</groupId>
-            <artifactId>geronimo-jms_1.1_spec</artifactId>
-            <scope>provided</scope>
-        </dependency>
-    </dependencies>
-
-</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java b/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java
deleted file mode 100644
index 0b746fc..0000000
--- a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java
+++ /dev/null
@@ -1,280 +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.util.IDUtil;
-
-import javax.jms.Message;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageListener;
-import javax.jms.ObjectMessage;
-import javax.jms.Session;
-import javax.jms.Topic;
-import javax.jms.TopicConnection;
-import javax.jms.TopicConnectionFactory;
-import javax.jms.TopicPublisher;
-import javax.jms.TopicSession;
-import javax.jms.TopicSubscriber;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NameNotFoundException;
-import javax.naming.NamingException;
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * Implementation of EventBridge that passes and receives events via JMS (Java Messaging
- * Service). JMSBridge uses "publish/subscribe" model for communication with external
- * agents.
- * 
- * @since 1.1
- */
-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_PROPERTY = "VM_ID";
-
-    protected String topicConnectionFactoryName;
-
-    protected TopicConnection sendConnection;
-    protected TopicSession sendSession;
-    protected TopicConnection receivedConnection;
-    protected TopicPublisher publisher;
-    protected TopicSubscriber subscriber;
-
-    public JMSBridge(EventSubject localSubject, String externalSubject) {
-        super(localSubject, externalSubject);
-    }
-
-    /**
-     * @since 1.2
-     */
-    public JMSBridge(Collection<EventSubject> localSubjects, String externalSubject) {
-        super(localSubjects, externalSubject);
-    }
-
-    /**
-     * @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_PROPERTY);
-            if (JMSBridge.VM_ID.equals(vmID)) {
-                return;
-            }
-
-            if (!(message instanceof ObjectMessage)) {
-                return;
-            }
-
-            ObjectMessage objectMessage = (ObjectMessage) message;
-            CayenneEvent event = messageObjectToEvent(objectMessage.getObject());
-            if (event != null) {
-                onExternalEvent(event);
-            }
-
-        }
-        catch (MessageFormatException mfex) {
-            // TODO: Andrus, 2/8/2006 logging... Log4J was removed to make this usable on
-            // the client
-        }
-        catch (Exception ex) {
-            // TODO: Andrus, 2/8/2006 logging... Log4J was removed to make this usable on
-            // the client
-        }
-    }
-
-    /**
-     * @return Name of javax.jms.TopicConnectionFactory accessible via JNDI.
-     */
-    public String getTopicConnectionFactoryName() {
-        return topicConnectionFactoryName;
-    }
-
-    public void setTopicConnectionFactoryName(String name) {
-        this.topicConnectionFactoryName = name;
-    }
-
-    /**
-     * Starts up JMS machinery for "publish/subscribe" model.
-     */
-    @Override
-    protected void startupExternal() throws Exception {
-        Context jndiContext = new InitialContext();
-        TopicConnectionFactory connectionFactory = (TopicConnectionFactory) jndiContext
-                .lookup(topicConnectionFactoryName);
-
-        Topic topic = null;
-
-        try {
-            topic = (Topic) jndiContext.lookup(externalSubject);
-        }
-        catch (NameNotFoundException ex) {
-            // can't find topic, try to create it
-            topic = topicNotFound(jndiContext, ex);
-
-            if (topic == null) {
-                throw ex;
-            }
-        }
-
-        // config publisher
-        if (receivesLocalEvents()) {
-            this.sendConnection = connectionFactory.createTopicConnection();
-            this.sendSession = sendConnection.createTopicSession(
-                    false,
-                    Session.AUTO_ACKNOWLEDGE);
-            this.publisher = sendSession.createPublisher(topic);
-        }
-
-        // config subscriber
-        if (receivesExternalEvents()) {
-            this.receivedConnection = connectionFactory.createTopicConnection();
-            this.subscriber = receivedConnection.createTopicSession(
-                    false,
-                    Session.AUTO_ACKNOWLEDGE).createSubscriber(topic);
-            this.subscriber.setMessageListener(this);
-            this.receivedConnection.start();
-        }
-    }
-
-    /**
-     * Attempts to create missing Topic. Since Topic creation is JMS-implementation
-     * specific, this task is left to subclasses. Current implementation simply rethrows
-     * the exception.
-     */
-    protected Topic topicNotFound(Context jndiContext, NamingException ex)
-            throws Exception {
-        throw ex;
-    }
-
-    /**
-     * Closes all resources used to communicate via JMS.
-     */
-    @Override
-    protected void shutdownExternal() throws Exception {
-        Exception lastException = null;
-
-        if (publisher != null) {
-            try {
-                publisher.close();
-            }
-            catch (Exception ex) {
-                lastException = ex;
-            }
-        }
-
-        if (subscriber != null) {
-            try {
-                subscriber.close();
-            }
-            catch (Exception ex) {
-                lastException = ex;
-            }
-        }
-
-        if (receivedConnection != null) {
-            try {
-                receivedConnection.close();
-            }
-            catch (Exception ex) {
-                lastException = ex;
-            }
-        }
-
-        if (sendSession != null) {
-            try {
-                sendSession.close();
-            }
-            catch (Exception ex) {
-                lastException = ex;
-            }
-        }
-
-        if (sendConnection != null) {
-            try {
-                sendConnection.close();
-            }
-            catch (Exception ex) {
-                lastException = ex;
-            }
-        }
-
-        publisher = null;
-        subscriber = null;
-        receivedConnection = null;
-        sendConnection = null;
-        sendSession = null;
-
-        if (lastException != null) {
-            throw lastException;
-        }
-    }
-
-    @Override
-    protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
-        ObjectMessage message = sendSession
-                .createObjectMessage(eventToMessageObject(localEvent));
-        message.setObjectProperty(JMSBridge.VM_ID_PROPERTY, JMSBridge.VM_ID);
-        publisher.publish(message);
-    }
-
-    /**
-     * Converts CayenneEvent to a serializable object that will be sent via JMS. Default
-     * implementation simply returns the event, but subclasses can customize this
-     * behavior.
-     */
-    protected Serializable eventToMessageObject(CayenneEvent event) throws Exception {
-        return event;
-    }
-
-    /**
-     * Converts a Serializable instance to CayenneEvent. Returns null if the object is not
-     * supported. Default implementation simply tries to cast the object to CayenneEvent,
-     * but subclasses can customize this behavior.
-     */
-    protected CayenneEvent messageObjectToEvent(Serializable object) throws Exception {
-        return (object instanceof CayenneEvent) ? (CayenneEvent) object : null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java b/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
deleted file mode 100644
index b7772d8..0000000
--- a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
+++ /dev/null
@@ -1,39 +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 java.util.Collection;
-import java.util.Map;
-
-/**
- * Factory to create JMSBridge instances.
- * 
- * @since 1.1
- */
-public class JMSBridgeFactory implements EventBridgeFactory {
-
-    /**
-     * @since 1.2
-     */
-    public EventBridge createEventBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) {
-        return new JMSBridge(localSubjects, externalSubject, properties);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
----------------------------------------------------------------------
diff --git a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java b/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
deleted file mode 100644
index 6a06faa..0000000
--- a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
+++ /dev/null
@@ -1,50 +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.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(JMSModule.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);
-    }
-
-}


[6/9] cayenne git commit: CAY-2404

Posted by nt...@apache.org.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/cayenne-tools-itest/src/test/resources/testmap-client.map.xml
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-tools-itest/src/test/resources/testmap-client.map.xml b/maven-plugins/cayenne-tools-itest/src/test/resources/testmap-client.map.xml
new file mode 100644
index 0000000..87145d5
--- /dev/null
+++ b/maven-plugins/cayenne-tools-itest/src/test/resources/testmap-client.map.xml
@@ -0,0 +1,730 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd"
+	 project-version="10">
+	<property name="defaultPackage" value="org.apache.cayenne.testdo.testmap"/>
+	<property name="defaultSuperclass" value="org.apache.cayenne.CayenneDataObject"/>
+	<property name="clientSupported" value="true"/>
+	<property name="defaultClientPackage" value="org.apache.cayenne.testdo.testmap.client"/>
+	<property name="defaultClientSuperclass" value="org.apache.cayenne.PersistentObject"/>
+	<procedure name="cayenne_tst_out_proc">
+		<procedure-parameter name="in_param" type="INTEGER" direction="in"/>
+		<procedure-parameter name="out_param" type="INTEGER" direction="out"/>
+	</procedure>
+	<procedure name="cayenne_tst_select_proc">
+		<procedure-parameter name="aName" type="VARCHAR" length="254" direction="in"/>
+		<procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
+	</procedure>
+	<procedure name="cayenne_tst_upd_proc">
+		<procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
+	</procedure>
+	<procedure name="cayenne_tst_upd_proc2"/>
+	<db-entity name="ARRAYS_ENTITY">
+		<db-attribute name="BYTE_ARRAY" type="VARBINARY" length="200"/>
+		<db-attribute name="BYTE_WRAPPER_ARRAY" type="VARBINARY" length="200"/>
+		<db-attribute name="CHAR_ARRAY" type="VARCHAR" length="200"/>
+		<db-attribute name="CHAR_WRAPPER_ARRAY" type="VARCHAR" length="200"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="ARTGROUP">
+		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" isMandatory="true" length="100"/>
+		<db-attribute name="PARENT_GROUP_ID" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="ARTIST">
+		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
+		<db-attribute name="DATE_OF_BIRTH" type="DATE"/>
+	</db-entity>
+	<db-entity name="ARTIST_CT">
+		<db-attribute name="ARTIST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
+		<db-attribute name="DATE_OF_BIRTH" type="DATE"/>
+	</db-entity>
+	<db-entity name="ARTIST_EXHIBIT">
+		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="ARTIST_GROUP">
+		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BIGDECIMAL_ENTITY">
+		<db-attribute name="BIGDECIMAL_FIELD" type="NUMERIC" length="12" scale="2"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BIGINTEGER_ENTITY">
+		<db-attribute name="BIG_INTEGER_FIELD" type="BIGINT"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BINARY_PK_TEST1">
+		<db-attribute name="BIN_ID" type="VARBINARY" isPrimaryKey="true" isMandatory="true" length="32"/>
+		<db-attribute name="NAME" type="VARCHAR" length="10"/>
+	</db-entity>
+	<db-entity name="BINARY_PK_TEST2">
+		<db-attribute name="DETAIL_NAME" type="VARCHAR" length="10"/>
+		<db-attribute name="FK_ID" type="VARBINARY" length="32"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BIT_TEST">
+		<db-attribute name="BIT_COLUMN" type="BIT" isMandatory="true"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BLOB_TEST">
+		<db-attribute name="BLOB_COL" type="BLOB"/>
+		<db-attribute name="BLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BOOLEAN_TEST">
+		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN" isMandatory="true"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CALENDAR_TEST">
+		<db-attribute name="CALENDAR_FIELD" type="TIMESTAMP"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CHARACTER_ENTITY">
+		<db-attribute name="CHARACTER_FIELD" type="CHAR" length="1"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CHAR_FK_TEST">
+		<db-attribute name="FK_COL" type="CHAR" length="10"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+		<db-attribute name="PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CHAR_PK_TEST">
+		<db-attribute name="OTHER_COL" type="CHAR" length="10"/>
+		<db-attribute name="PK_COL" type="CHAR" isPrimaryKey="true" isMandatory="true" length="10"/>
+	</db-entity>
+	<db-entity name="CLOB_TEST">
+		<db-attribute name="CLOB_COL" type="CLOB"/>
+		<db-attribute name="CLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CLOB_TEST_RELATION">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="ID_CLOB" type="INTEGER" isMandatory="true"/>
+		<db-attribute name="VALUE" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="COMPOUND_FK_TEST">
+		<db-attribute name="F_KEY1" type="VARCHAR" length="20"/>
+		<db-attribute name="F_KEY2" type="VARCHAR" length="20"/>
+		<db-attribute name="NAME" type="VARCHAR" length="255"/>
+		<db-attribute name="PKEY" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="COMPOUND_PK_TEST">
+		<db-attribute name="KEY1" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
+		<db-attribute name="KEY2" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
+		<db-attribute name="NAME" type="VARCHAR" length="255"/>
+	</db-entity>
+	<db-entity name="DATE_TEST">
+		<db-attribute name="DATE_COLUMN" type="DATE"/>
+		<db-attribute name="DATE_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
+		<db-attribute name="TIME_COLUMN" type="TIME"/>
+	</db-entity>
+	<db-entity name="DECIMAL_PK_TST">
+		<db-attribute name="DECIMAL_PK" type="DECIMAL" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="ENUM_ENTITY">
+		<db-attribute name="ENUM_ATTRIBUTE" type="VARCHAR" length="250"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="EXHIBIT">
+		<db-attribute name="CLOSING_DATE" type="TIMESTAMP" isMandatory="true"/>
+		<db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="GALLERY_ID" type="INTEGER" isMandatory="true"/>
+		<db-attribute name="OPENING_DATE" type="TIMESTAMP" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="EXTENDED_TYPE_TEST">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="200"/>
+	</db-entity>
+	<db-entity name="FLOAT_TEST">
+		<db-attribute name="FLOAT_COL" type="FLOAT"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="GALLERY">
+		<db-attribute name="GALLERY_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="GALLERY_NAME" type="VARCHAR" isMandatory="true" length="100"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_COMP_KEY">
+		<db-attribute name="AUTO_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+		<db-attribute name="PROPAGATED_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_COMP_M">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_DEP">
+		<db-attribute name="GENERATED_COLUMN_FK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_TEST">
+		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="250"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_TEST2">
+		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="GENERATED_F1">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="GENERATED_F2">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="GENERATED_JOIN">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+		<db-attribute name="ID1" type="INTEGER"/>
+		<db-attribute name="ID2" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="LONG_ENTITY">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="LONG_FIELD" type="BIGINT"/>
+	</db-entity>
+	<db-entity name="MEANINGFUL_PK_DEP">
+		<db-attribute name="DESCR" type="VARCHAR" length="50"/>
+		<db-attribute name="MASTER_PK" type="INTEGER"/>
+		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="MEANINGFUL_PK_TEST1">
+		<db-attribute name="DESCR" type="VARCHAR" length="50"/>
+		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="MIXED_PERSISTENCE_STRATEGY">
+		<db-attribute name="DESCRIPTION" type="VARCHAR" length="200"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="200"/>
+	</db-entity>
+	<db-entity name="MIXED_PERSISTENCE_STRATEGY2">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="MASTER_ID" type="INTEGER"/>
+		<db-attribute name="NAME" type="VARCHAR" length="200"/>
+	</db-entity>
+	<db-entity name="NO_PK_TEST">
+		<db-attribute name="ATTRIBUTE1" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="PAINTING">
+		<db-attribute name="ARTIST_ID" type="BIGINT"/>
+		<db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
+		<db-attribute name="GALLERY_ID" type="INTEGER"/>
+		<db-attribute name="PAINTING_DESCRIPTION" type="VARCHAR" length="255"/>
+		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
+	</db-entity>
+	<db-entity name="PAINTING1">
+		<db-attribute name="ARTIST_ID" type="BIGINT"/>
+		<db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
+		<db-attribute name="GALLERY_ID" type="INTEGER"/>
+		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
+	</db-entity>
+	<db-entity name="PAINTING_INFO">
+		<db-attribute name="IMAGE_BLOB" type="LONGVARBINARY"/>
+		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="TEXT_REVIEW" type="LONGVARCHAR"/>
+	</db-entity>
+	<db-entity name="PRIMITIVES_TEST">
+		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="INT_COLUMN" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="SERIALIZABLE_ENTITY">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="SERIALIZABLE_FIELD" type="BLOB"/>
+	</db-entity>
+	<db-entity name="SMALLINT_TEST">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="SMALLINT_COL" type="SMALLINT"/>
+	</db-entity>
+	<db-entity name="TINYINT_TEST">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="TINYINT_COL" type="TINYINT"/>
+	</db-entity>
+	<db-entity name="TYPES_MAPPING_TEST1">
+		<db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="BIGINT_COLUMN" type="BIGINT"/>
+		<db-attribute name="BIT_COLUMN" type="BIT"/>
+		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
+		<db-attribute name="CHAR_COLUMN" type="CHAR" length="254"/>
+		<db-attribute name="CLOB_COLUMN" type="CLOB"/>
+		<db-attribute name="DATE_COLUMN" type="DATE"/>
+		<db-attribute name="DECIMAL_COLUMN" type="DECIMAL" length="12" scale="5"/>
+		<db-attribute name="DOUBLE_COLUMN" type="DOUBLE" scale="7"/>
+		<db-attribute name="FLOAT_COLUMN" type="FLOAT" scale="3"/>
+		<db-attribute name="INTEGER_COLUMN" type="INTEGER"/>
+		<db-attribute name="LONGVARCHAR_COLUMN" type="LONGVARCHAR"/>
+		<db-attribute name="NUMERIC_COLUMN" type="NUMERIC" length="12" scale="5"/>
+		<db-attribute name="REAL_COLUMN" type="REAL" scale="5"/>
+		<db-attribute name="SMALLINT_COLUMN" type="SMALLINT"/>
+		<db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
+		<db-attribute name="TIME_COLUMN" type="TIME"/>
+		<db-attribute name="TINYINT_COLUMN" type="TINYINT"/>
+		<db-attribute name="VARCHAR_COLUMN" type="VARCHAR" length="255"/>
+	</db-entity>
+	<db-entity name="TYPES_MAPPING_TEST2">
+		<db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="BINARY_COLUMN" type="BINARY" length="14"/>
+		<db-attribute name="BLOB_COLUMN" type="BLOB"/>
+		<db-attribute name="LONGVARBINARY_COLUMN" type="LONGVARBINARY"/>
+		<db-attribute name="VARBINARY_COLUMN" type="VARBINARY" length="1000"/>
+	</db-entity>
+	<db-entity name="UUID_TEST">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="UUID" type="VARCHAR" length="100"/>
+	</db-entity>
+	<obj-entity name="ArraysEntity" className="org.apache.cayenne.testdo.misc_types.ArraysEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.ArraysEntity" dbEntityName="ARRAYS_ENTITY">
+		<obj-attribute name="byteArray" type="byte[]" db-attribute-path="BYTE_ARRAY"/>
+		<obj-attribute name="byteWrapperArray" type="java.lang.Byte[]" db-attribute-path="BYTE_WRAPPER_ARRAY"/>
+		<obj-attribute name="charArray" type="char[]" db-attribute-path="CHAR_ARRAY"/>
+		<obj-attribute name="charWrapperArray" type="java.lang.Character[]" db-attribute-path="CHAR_WRAPPER_ARRAY"/>
+	</obj-entity>
+	<obj-entity name="ArtGroup" className="org.apache.cayenne.testdo.testmap.ArtGroup" clientClassName="org.apache.cayenne.testdo.testmap.client.ArtGroup" dbEntityName="ARTGROUP">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="Artist" className="org.apache.cayenne.testdo.testmap.Artist" clientClassName="org.apache.cayenne.testdo.testmap.client.Artist" dbEntityName="ARTIST">
+		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
+		<obj-attribute name="dateOfBirth" type="java.util.Date" db-attribute-path="DATE_OF_BIRTH"/>
+	</obj-entity>
+	<obj-entity name="ArtistCallbackTest" className="org.apache.cayenne.testdo.testmap.ArtistCallbackTest" clientClassName="org.apache.cayenne.testdo.testmap.client.ArtistCallbackTest" dbEntityName="ARTIST_CT">
+		<obj-attribute name="artistName" type="java.lang.String"/>
+		<obj-attribute name="dateOfBirth" type="java.util.Date"/>
+		<post-add method-name="prePersistEntityObjEntity"/>
+		<post-persist method-name="postPersistEntityObjEntity"/>
+		<pre-update method-name="preUpdateEntityObjEntity"/>
+		<post-update method-name="postUpdateEntityObjEntity"/>
+		<pre-remove method-name="preRemoveEntityObjEntity"/>
+		<post-remove method-name="postRemoveEntityObjEntity"/>
+		<post-load method-name="postLoadEntityObjEntity"/>
+	</obj-entity>
+	<obj-entity name="ArtistExhibit" className="org.apache.cayenne.testdo.testmap.ArtistExhibit" clientClassName="org.apache.cayenne.testdo.testmap.client.ArtistExhibit" dbEntityName="ARTIST_EXHIBIT"/>
+	<obj-entity name="BigDecimalEntity" className="org.apache.cayenne.testdo.numeric_types.BigDecimalEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BigDecimalEntity" dbEntityName="BIGDECIMAL_ENTITY">
+		<obj-attribute name="bigDecimalField" type="java.math.BigDecimal" db-attribute-path="BIGDECIMAL_FIELD"/>
+	</obj-entity>
+	<obj-entity name="BigIntegerEntity" className="org.apache.cayenne.testdo.numeric_types.BigIntegerEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BigIntegerEntity" dbEntityName="BIGINTEGER_ENTITY">
+		<obj-attribute name="bigIntegerField" type="java.math.BigInteger" db-attribute-path="BIG_INTEGER_FIELD"/>
+	</obj-entity>
+	<obj-entity name="BinaryPKTest1" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest1" clientClassName="org.apache.cayenne.testdo.testmap.client.BinaryPKTest1" dbEntityName="BINARY_PK_TEST1">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="BinaryPKTest2" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest2" clientClassName="org.apache.cayenne.testdo.testmap.client.BinaryPKTest2" dbEntityName="BINARY_PK_TEST2">
+		<obj-attribute name="detailName" type="java.lang.String" db-attribute-path="DETAIL_NAME"/>
+	</obj-entity>
+	<obj-entity name="BitNumberTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitNumberTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BitNumberTestEntity" dbEntityName="BIT_TEST">
+		<obj-attribute name="bitColumn" type="java.lang.Integer" db-attribute-path="BIT_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="BitTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BitTestEntity" dbEntityName="BIT_TEST">
+		<obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="BlobTestEntity" className="org.apache.cayenne.testdo.lob.BlobTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BlobTestEntity" dbEntityName="BLOB_TEST">
+		<obj-attribute name="blobCol" type="byte[]" db-attribute-path="BLOB_COL"/>
+	</obj-entity>
+	<obj-entity name="BooleanTestEntity" className="org.apache.cayenne.testdo.numeric_types.BooleanTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BooleanTestEntity" dbEntityName="BOOLEAN_TEST">
+		<obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="CalendarEntity" className="org.apache.cayenne.testdo.date_time.CalendarEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CalendarEntity" dbEntityName="CALENDAR_TEST">
+		<obj-attribute name="calendarField" type="java.util.Calendar" db-attribute-path="CALENDAR_FIELD"/>
+	</obj-entity>
+	<obj-entity name="CharFkTestEntity" className="org.apache.cayenne.testdo.compound.CharFkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CharFkTestEntity" dbEntityName="CHAR_FK_TEST">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="CharPkTestEntity" className="org.apache.cayenne.testdo.compound.CharPkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CharPkTestEntity" dbEntityName="CHAR_PK_TEST">
+		<obj-attribute name="otherCol" type="java.lang.String" db-attribute-path="OTHER_COL"/>
+		<obj-attribute name="pkCol" type="java.lang.String" db-attribute-path="PK_COL"/>
+	</obj-entity>
+	<obj-entity name="CharacterEntity" className="org.apache.cayenne.testdo.misc_types.CharacterEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CharacterEntity" dbEntityName="CHARACTER_ENTITY">
+		<obj-attribute name="characterField" type="java.lang.Character" db-attribute-path="CHARACTER_FIELD"/>
+	</obj-entity>
+	<obj-entity name="ClobTestEntity" className="org.apache.cayenne.testdo.lob.ClobTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.ClobTestEntity" dbEntityName="CLOB_TEST">
+		<obj-attribute name="clobCol" type="java.lang.String" db-attribute-path="CLOB_COL"/>
+	</obj-entity>
+	<obj-entity name="ClobTestRelation" className="org.apache.cayenne.testdo.lob.ClobTestRelation" clientClassName="org.apache.cayenne.testdo.testmap.client.ClobTestRelation" dbEntityName="CLOB_TEST_RELATION">
+		<obj-attribute name="id" type="java.lang.Integer" db-attribute-path="ID"/>
+		<obj-attribute name="value" type="java.lang.Integer" db-attribute-path="VALUE"/>
+	</obj-entity>
+	<obj-entity name="CompoundFkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundFkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CompoundFkTestEntity" dbEntityName="COMPOUND_FK_TEST">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="CompoundPainting" className="org.apache.cayenne.testdo.testmap.CompoundPainting" clientClassName="org.apache.cayenne.testdo.testmap.client.CompoundPainting" dbEntityName="PAINTING">
+		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="toArtist.ARTIST_NAME"/>
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="toGallery.GALLERY_NAME"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
+	</obj-entity>
+	<obj-entity name="CompoundPkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundPkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CompoundPkTestEntity" dbEntityName="COMPOUND_PK_TEST">
+		<obj-attribute name="key1" type="java.lang.String" db-attribute-path="KEY1"/>
+		<obj-attribute name="key2" type="java.lang.String" db-attribute-path="KEY2"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="DateTestEntity" className="org.apache.cayenne.testdo.date_time.DateTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.DateTestEntity" dbEntityName="DATE_TEST">
+		<obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
+		<obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
+		<obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="DecimalPKTest1" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTest1" clientClassName="org.apache.cayenne.testdo.testmap.client.DecimalPKTest1" dbEntityName="DECIMAL_PK_TST">
+		<obj-attribute name="decimalPK" type="java.lang.Double" db-attribute-path="DECIMAL_PK"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="DecimalPKTestEntity" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.DecimalPKTestEntity" dbEntityName="DECIMAL_PK_TST">
+		<obj-attribute name="decimalPK" type="java.math.BigDecimal" db-attribute-path="DECIMAL_PK"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="EnumEntity" className="org.apache.cayenne.testdo.enum_test.EnumEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.EnumEntity" dbEntityName="ENUM_ENTITY">
+		<obj-attribute name="enumAttribute" type="org.apache.cayenne.testdo.enum_test.Enum1" db-attribute-path="ENUM_ATTRIBUTE"/>
+	</obj-entity>
+	<obj-entity name="Exhibit" className="org.apache.cayenne.testdo.testmap.Exhibit" clientClassName="org.apache.cayenne.testdo.testmap.client.Exhibit" dbEntityName="EXHIBIT">
+		<obj-attribute name="closingDate" type="java.util.Date" db-attribute-path="CLOSING_DATE"/>
+		<obj-attribute name="openingDate" type="java.util.Date" db-attribute-path="OPENING_DATE"/>
+	</obj-entity>
+	<obj-entity name="ExtendedTypeEntity" className="org.apache.cayenne.testdo.extended_type.ExtendedTypeEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.ExtendedTypeEntity" dbEntityName="EXTENDED_TYPE_TEST">
+		<obj-attribute name="name" type="org.apache.cayenne.testdo.extended_type.StringET1" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="Gallery" className="org.apache.cayenne.testdo.testmap.Gallery" clientClassName="org.apache.cayenne.testdo.testmap.client.Gallery" dbEntityName="GALLERY">
+		<obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="GALLERY_NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnCompKey" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompKey" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnCompKey" dbEntityName="GENERATED_COLUMN_COMP_KEY">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnCompMaster" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompMaster" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnCompMaster" dbEntityName="GENERATED_COLUMN_COMP_M">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnDep" className="org.apache.cayenne.testdo.generated.GeneratedColumnDep" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnDep" dbEntityName="GENERATED_COLUMN_DEP">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnTest2" className="org.apache.cayenne.testdo.generated.GeneratedColumnTest2" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnTest2" dbEntityName="GENERATED_COLUMN_TEST2">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnTestEntity" className="org.apache.cayenne.testdo.generated.GeneratedColumnTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedF1" className="org.apache.cayenne.testdo.generated.GeneratedF1" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedF1" dbEntityName="GENERATED_F1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject"/>
+	<obj-entity name="GeneratedF2" className="org.apache.cayenne.testdo.generated.GeneratedF2" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedF2" dbEntityName="GENERATED_F2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject"/>
+	<obj-entity name="LongEntity" className="org.apache.cayenne.testdo.numeric_types.LongEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.LongEntity" dbEntityName="LONG_ENTITY">
+		<obj-attribute name="longField" type="java.lang.Long" db-attribute-path="LONG_FIELD"/>
+	</obj-entity>
+	<obj-entity name="MeaningfulGeneratedColumnTestEntity" className="org.apache.cayenne.testdo.testmap.MeaningfulGeneratedColumnTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.MeaningfulGeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
+		<obj-attribute name="generatedColumn" type="java.lang.Integer" db-attribute-path="GENERATED_COLUMN"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="MeaningfulPKDep" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKDep" clientClassName="org.apache.cayenne.testdo.testmap.client.MeaningfulPKDep" dbEntityName="MEANINGFUL_PK_DEP">
+		<obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
+	</obj-entity>
+	<obj-entity name="MeaningfulPKTest1" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKTest1" clientClassName="org.apache.cayenne.testdo.testmap.client.MeaningfulPKTest1" dbEntityName="MEANINGFUL_PK_TEST1">
+		<obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
+		<obj-attribute name="pkAttribute" type="java.lang.Integer" db-attribute-path="PK_ATTRIBUTE"/>
+	</obj-entity>
+	<obj-entity name="MixedPersistenceStrategy" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy" clientClassName="org.apache.cayenne.testdo.testmap.client.MixedPersistenceStrategy" dbEntityName="MIXED_PERSISTENCE_STRATEGY">
+		<obj-attribute name="description" type="java.lang.String" db-attribute-path="DESCRIPTION"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="MixedPersistenceStrategy2" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy2" clientClassName="org.apache.cayenne.testdo.testmap.client.MixedPersistenceStrategy2" dbEntityName="MIXED_PERSISTENCE_STRATEGY2">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="NoPkTestEntity" className="org.apache.cayenne.testdo.no_pk.NoPkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.NoPkTestEntity" dbEntityName="NO_PK_TEST">
+		<obj-attribute name="attribute1" type="java.lang.Integer" db-attribute-path="ATTRIBUTE1"/>
+	</obj-entity>
+	<obj-entity name="Painting" className="org.apache.cayenne.testdo.testmap.Painting" clientClassName="org.apache.cayenne.testdo.testmap.client.Painting" dbEntityName="PAINTING" superClassName="org.apache.cayenne.testdo.testmap.ArtDataObject">
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="paintingDescription" type="java.lang.String" db-attribute-path="PAINTING_DESCRIPTION"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+	</obj-entity>
+	<obj-entity name="Painting1" className="org.apache.cayenne.testdo.testmap.Painting1" clientClassName="org.apache.cayenne.testdo.testmap.client.Painting1" dbEntityName="PAINTING1">
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+	</obj-entity>
+	<obj-entity name="PaintingInfo" className="org.apache.cayenne.testdo.testmap.PaintingInfo" clientClassName="org.apache.cayenne.testdo.testmap.client.PaintingInfo" dbEntityName="PAINTING_INFO">
+		<obj-attribute name="imageBlob" type="byte[]" db-attribute-path="IMAGE_BLOB"/>
+		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="TEXT_REVIEW"/>
+	</obj-entity>
+	<obj-entity name="PrimitivesTestEntity" className="org.apache.cayenne.testdo.primitive.PrimitivesTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.PrimitivesTestEntity" dbEntityName="PRIMITIVES_TEST">
+		<obj-attribute name="booleanColumn" type="boolean" db-attribute-path="BOOLEAN_COLUMN"/>
+		<obj-attribute name="intColumn" type="int" db-attribute-path="INT_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="ROArtist" className="org.apache.cayenne.testdo.testmap.ROArtist" clientClassName="org.apache.cayenne.testdo.testmap.client.ROArtist" readOnly="true" dbEntityName="ARTIST">
+		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
+		<obj-attribute name="dateOfBirth" type="java.sql.Date" db-attribute-path="DATE_OF_BIRTH"/>
+	</obj-entity>
+	<obj-entity name="ROPainting" className="org.apache.cayenne.testdo.testmap.ROPainting" clientClassName="org.apache.cayenne.testdo.testmap.client.ROPainting" readOnly="true" dbEntityName="PAINTING">
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+	</obj-entity>
+	<obj-entity name="RWCompoundPainting" className="org.apache.cayenne.testdo.testmap.RWCompoundPainting" clientClassName="org.apache.cayenne.testdo.testmap.client.RWCompoundPainting" dbEntityName="PAINTING">
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
+	</obj-entity>
+	<obj-entity name="ReturnTypesMap1" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap1" clientClassName="org.apache.cayenne.testdo.testmap.client.ReturnTypesMap1" dbEntityName="TYPES_MAPPING_TEST1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+		<obj-attribute name="bigintColumn" type="java.lang.Long" db-attribute-path="BIGINT_COLUMN"/>
+		<obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
+		<obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
+		<obj-attribute name="charColumn" type="java.lang.String" db-attribute-path="CHAR_COLUMN"/>
+		<obj-attribute name="clobColumn" type="java.lang.String" db-attribute-path="CLOB_COLUMN"/>
+		<obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
+		<obj-attribute name="decimalColumn" type="java.math.BigDecimal" db-attribute-path="DECIMAL_COLUMN"/>
+		<obj-attribute name="doubleColumn" type="java.lang.Double" db-attribute-path="DOUBLE_COLUMN"/>
+		<obj-attribute name="floatColumn" type="java.lang.Float" db-attribute-path="FLOAT_COLUMN"/>
+		<obj-attribute name="integerColumn" type="java.lang.Integer" db-attribute-path="INTEGER_COLUMN"/>
+		<obj-attribute name="longvarcharColumn" type="java.lang.String" db-attribute-path="LONGVARCHAR_COLUMN"/>
+		<obj-attribute name="numericColumn" type="java.math.BigDecimal" db-attribute-path="NUMERIC_COLUMN"/>
+		<obj-attribute name="realColumn" type="java.lang.Float" db-attribute-path="REAL_COLUMN"/>
+		<obj-attribute name="smallintColumn" type="java.lang.Short" db-attribute-path="SMALLINT_COLUMN"/>
+		<obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
+		<obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
+		<obj-attribute name="tinyintColumn" type="java.lang.Byte" db-attribute-path="TINYINT_COLUMN"/>
+		<obj-attribute name="varcharColumn" type="java.lang.String" db-attribute-path="VARCHAR_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="ReturnTypesMap2" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap2" clientClassName="org.apache.cayenne.testdo.testmap.client.ReturnTypesMap2" dbEntityName="TYPES_MAPPING_TEST2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+		<obj-attribute name="binaryColumn" type="byte[]" db-attribute-path="BINARY_COLUMN"/>
+		<obj-attribute name="blobColumn" type="byte[]" db-attribute-path="BLOB_COLUMN"/>
+		<obj-attribute name="longvarbinaryColumn" type="byte[]" db-attribute-path="LONGVARBINARY_COLUMN"/>
+		<obj-attribute name="varbinaryColumn" type="byte[]" db-attribute-path="VARBINARY_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="SerializableEntity" className="org.apache.cayenne.testdo.misc_types.SerializableEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.SerializableEntity" dbEntityName="SERIALIZABLE_ENTITY">
+		<obj-attribute name="serializableField" type="org.apache.cayenne.MockSerializable" db-attribute-path="SERIALIZABLE_FIELD"/>
+	</obj-entity>
+	<obj-entity name="SmallintTestEntity" className="org.apache.cayenne.testdo.numeric_types.SmallintTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.SmallintTestEntity" dbEntityName="SMALLINT_TEST">
+		<obj-attribute name="smallintCol" type="java.lang.Short" db-attribute-path="SMALLINT_COL"/>
+	</obj-entity>
+	<obj-entity name="SubPainting" className="org.apache.cayenne.testdo.testmap.SubPainting" clientClassName="org.apache.cayenne.testdo.testmap.client.SubPainting" dbEntityName="PAINTING">
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+	</obj-entity>
+	<obj-entity name="TinyintTestEntity" className="org.apache.cayenne.testdo.numeric_types.TinyintTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.TinyintTestEntity" dbEntityName="TINYINT_TEST">
+		<obj-attribute name="tinyintCol" type="java.lang.Byte" db-attribute-path="TINYINT_COL"/>
+	</obj-entity>
+	<obj-entity name="UuidTestEntity" className="org.apache.cayenne.testdo.uuid.UuidTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.UuidTestEntity" dbEntityName="UUID_TEST">
+		<obj-attribute name="uuid" type="java.util.UUID" db-attribute-path="UUID"/>
+	</obj-entity>
+	<db-relationship name="artistGroupArray" source="ARTGROUP" target="ARTIST_GROUP" toMany="true">
+		<db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
+	</db-relationship>
+	<db-relationship name="toChildGroups" source="ARTGROUP" target="ARTGROUP" toMany="true">
+		<db-attribute-pair source="GROUP_ID" target="PARENT_GROUP_ID"/>
+	</db-relationship>
+	<db-relationship name="toParentGroup" source="ARTGROUP" target="ARTGROUP">
+		<db-attribute-pair source="PARENT_GROUP_ID" target="GROUP_ID"/>
+	</db-relationship>
+	<db-relationship name="artistExhibitArray" source="ARTIST" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="artistGroupArray" source="ARTIST" target="ARTIST_GROUP" toMany="true">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="paintingArray" source="ARTIST" target="PAINTING" toMany="true">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="toArtist" source="ARTIST_EXHIBIT" target="ARTIST">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="toExhibit" source="ARTIST_EXHIBIT" target="EXHIBIT">
+		<db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
+	</db-relationship>
+	<db-relationship name="toArtist" source="ARTIST_GROUP" target="ARTIST">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="toGroup" source="ARTIST_GROUP" target="ARTGROUP">
+		<db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
+	</db-relationship>
+	<db-relationship name="binaryPKDetails" source="BINARY_PK_TEST1" target="BINARY_PK_TEST2" toMany="true">
+		<db-attribute-pair source="BIN_ID" target="FK_ID"/>
+	</db-relationship>
+	<db-relationship name="toBinaryPKMaster" source="BINARY_PK_TEST2" target="BINARY_PK_TEST1">
+		<db-attribute-pair source="FK_ID" target="BIN_ID"/>
+	</db-relationship>
+	<db-relationship name="toCharPK" source="CHAR_FK_TEST" target="CHAR_PK_TEST">
+		<db-attribute-pair source="FK_COL" target="PK_COL"/>
+	</db-relationship>
+	<db-relationship name="charFKs" source="CHAR_PK_TEST" target="CHAR_FK_TEST" toMany="true">
+		<db-attribute-pair source="PK_COL" target="FK_COL"/>
+	</db-relationship>
+	<db-relationship name="clob" source="CLOB_TEST" target="CLOB_TEST_RELATION" toMany="true">
+		<db-attribute-pair source="CLOB_TEST_ID" target="ID_CLOB"/>
+	</db-relationship>
+	<db-relationship name="CLOB_REL" source="CLOB_TEST_RELATION" target="CLOB_TEST">
+		<db-attribute-pair source="ID_CLOB" target="CLOB_TEST_ID"/>
+	</db-relationship>
+	<db-relationship name="toCompoundPk" source="COMPOUND_FK_TEST" target="COMPOUND_PK_TEST">
+		<db-attribute-pair source="F_KEY1" target="KEY1"/>
+		<db-attribute-pair source="F_KEY2" target="KEY2"/>
+	</db-relationship>
+	<db-relationship name="compoundFkArray" source="COMPOUND_PK_TEST" target="COMPOUND_FK_TEST" toMany="true">
+		<db-attribute-pair source="KEY1" target="F_KEY1"/>
+		<db-attribute-pair source="KEY2" target="F_KEY2"/>
+	</db-relationship>
+	<db-relationship name="artistExhibitArray" source="EXHIBIT" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
+	</db-relationship>
+	<db-relationship name="toGallery" source="EXHIBIT" target="GALLERY">
+		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+	</db-relationship>
+	<db-relationship name="exhibitArray" source="GALLERY" target="EXHIBIT" toMany="true">
+		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+	</db-relationship>
+	<db-relationship name="paintingArray" source="GALLERY" target="PAINTING" toMany="true">
+		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+	</db-relationship>
+	<db-relationship name="toMaster" source="GENERATED_COLUMN_COMP_KEY" target="GENERATED_COLUMN_COMP_M">
+		<db-attribute-pair source="PROPAGATED_PK" target="ID"/>
+	</db-relationship>
+	<db-relationship name="toDetail" source="GENERATED_COLUMN_COMP_M" target="GENERATED_COLUMN_COMP_KEY" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="ID" target="PROPAGATED_PK"/>
+	</db-relationship>
+	<db-relationship name="toMaster" source="GENERATED_COLUMN_DEP" target="GENERATED_COLUMN_TEST">
+		<db-attribute-pair source="GENERATED_COLUMN_FK" target="GENERATED_COLUMN"/>
+	</db-relationship>
+	<db-relationship name="toDep" source="GENERATED_COLUMN_TEST" target="GENERATED_COLUMN_DEP" toDependentPK="true">
+		<db-attribute-pair source="GENERATED_COLUMN" target="GENERATED_COLUMN_FK"/>
+	</db-relationship>
+	<db-relationship name="join" source="GENERATED_F1" target="GENERATED_JOIN" toMany="true">
+		<db-attribute-pair source="ID" target="ID1"/>
+	</db-relationship>
+	<db-relationship name="join" source="GENERATED_F2" target="GENERATED_JOIN" toMany="true">
+		<db-attribute-pair source="ID" target="ID2"/>
+	</db-relationship>
+	<db-relationship name="f1" source="GENERATED_JOIN" target="GENERATED_F1">
+		<db-attribute-pair source="ID1" target="ID"/>
+	</db-relationship>
+	<db-relationship name="f2" source="GENERATED_JOIN" target="GENERATED_F2">
+		<db-attribute-pair source="ID2" target="ID"/>
+	</db-relationship>
+	<db-relationship name="toMeaningfulPK" source="MEANINGFUL_PK_DEP" target="MEANINGFUL_PK_TEST1">
+		<db-attribute-pair source="MASTER_PK" target="PK_ATTRIBUTE"/>
+	</db-relationship>
+	<db-relationship name="meaningfulPKDepArray" source="MEANINGFUL_PK_TEST1" target="MEANINGFUL_PK_DEP" toMany="true">
+		<db-attribute-pair source="PK_ATTRIBUTE" target="MASTER_PK"/>
+	</db-relationship>
+	<db-relationship name="details" source="MIXED_PERSISTENCE_STRATEGY" target="MIXED_PERSISTENCE_STRATEGY2" toMany="true">
+		<db-attribute-pair source="ID" target="MASTER_ID"/>
+	</db-relationship>
+	<db-relationship name="master" source="MIXED_PERSISTENCE_STRATEGY2" target="MIXED_PERSISTENCE_STRATEGY">
+		<db-attribute-pair source="MASTER_ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="toArtist" source="PAINTING" target="ARTIST">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="toGallery" source="PAINTING" target="GALLERY">
+		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+	</db-relationship>
+	<db-relationship name="toPaintingInfo" source="PAINTING" target="PAINTING_INFO" toDependentPK="true">
+		<db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
+	</db-relationship>
+	<db-relationship name="toArtist" source="PAINTING1" target="ARTIST">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="painting" source="PAINTING_INFO" target="PAINTING">
+		<db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
+	</db-relationship>
+	<obj-relationship name="artistArray" source="ArtGroup" target="Artist" deleteRule="Nullify" db-relationship-path="artistGroupArray.toArtist"/>
+	<obj-relationship name="childGroupsArray" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toChildGroups"/>
+	<obj-relationship name="toParentGroup" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toParentGroup"/>
+	<obj-relationship name="artistExhibitArray" source="Artist" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
+	<obj-relationship name="groupArray" source="Artist" target="ArtGroup" deleteRule="Cascade" db-relationship-path="artistGroupArray.toGroup"/>
+	<obj-relationship name="paintingArray" source="Artist" target="Painting" deleteRule="Cascade" db-relationship-path="paintingArray"/>
+	<obj-relationship name="toArtist" source="ArtistExhibit" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<obj-relationship name="toExhibit" source="ArtistExhibit" target="Exhibit" deleteRule="Nullify" db-relationship-path="toExhibit"/>
+	<obj-relationship name="binaryPKDetails" source="BinaryPKTest1" target="BinaryPKTest2" db-relationship-path="binaryPKDetails"/>
+	<obj-relationship name="toBinaryPKMaster" source="BinaryPKTest2" target="BinaryPKTest1" db-relationship-path="toBinaryPKMaster"/>
+	<obj-relationship name="toCharPK" source="CharFkTestEntity" target="CharPkTestEntity" db-relationship-path="toCharPK"/>
+	<obj-relationship name="charFKs" source="CharPkTestEntity" target="CharFkTestEntity" db-relationship-path="charFKs"/>
+	<obj-relationship name="clobValue" source="ClobTestEntity" target="ClobTestRelation" db-relationship-path="clob"/>
+	<obj-relationship name="clobId" source="ClobTestRelation" target="ClobTestEntity" db-relationship-path="CLOB_REL"/>
+	<obj-relationship name="toCompoundPk" source="CompoundFkTestEntity" target="CompoundPkTestEntity" db-relationship-path="toCompoundPk"/>
+	<obj-relationship name="toArtist" source="CompoundPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<obj-relationship name="toGallery" source="CompoundPainting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
+	<obj-relationship name="toPaintingInfo" source="CompoundPainting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
+	<obj-relationship name="compoundFkArray" source="CompoundPkTestEntity" target="CompoundFkTestEntity" db-relationship-path="compoundFkArray"/>
+	<obj-relationship name="artistExhibitArray" source="Exhibit" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
+	<obj-relationship name="toGallery" source="Exhibit" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
+	<obj-relationship name="exhibitArray" source="Gallery" target="Exhibit" deleteRule="Cascade" db-relationship-path="exhibitArray"/>
+	<obj-relationship name="paintingArray" source="Gallery" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
+	<obj-relationship name="toMaster" source="GeneratedColumnCompKey" target="GeneratedColumnCompMaster" db-relationship-path="toMaster"/>
+	<obj-relationship name="toDetail" source="GeneratedColumnCompMaster" target="GeneratedColumnCompKey" db-relationship-path="toDetail"/>
+	<obj-relationship name="toMaster" source="GeneratedColumnDep" target="GeneratedColumnTestEntity" db-relationship-path="toMaster"/>
+	<obj-relationship name="toDep" source="GeneratedColumnTestEntity" target="GeneratedColumnDep" db-relationship-path="toDep"/>
+	<obj-relationship name="f2" source="GeneratedF1" target="GeneratedF2" deleteRule="Nullify" db-relationship-path="join.f2"/>
+	<obj-relationship name="f1" source="GeneratedF2" target="GeneratedF1" deleteRule="Nullify" db-relationship-path="join.f1"/>
+	<obj-relationship name="toMeaningfulPK" source="MeaningfulPKDep" target="MeaningfulPKTest1" db-relationship-path="toMeaningfulPK"/>
+	<obj-relationship name="meaningfulPKDepArray" source="MeaningfulPKTest1" target="MeaningfulPKDep" db-relationship-path="meaningfulPKDepArray"/>
+	<obj-relationship name="details" source="MixedPersistenceStrategy" target="MixedPersistenceStrategy2" db-relationship-path="details"/>
+	<obj-relationship name="master" source="MixedPersistenceStrategy2" target="MixedPersistenceStrategy" db-relationship-path="master"/>
+	<obj-relationship name="toArtist" source="Painting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<obj-relationship name="toGallery" source="Painting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
+	<obj-relationship name="toPaintingInfo" source="Painting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
+	<obj-relationship name="toArtist" source="Painting1" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<obj-relationship name="painting" source="PaintingInfo" target="Painting" deleteRule="Nullify" db-relationship-path="painting"/>
+	<obj-relationship name="paintingArray" source="ROArtist" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
+	<obj-relationship name="toArtist" source="ROPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<query name="EjbqlQueryTest" type="EJBQLQuery">
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<ejbql><![CDATA[select a from Artist a]]></ejbql>
+	</query>
+	<query name="NonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap-client">
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
+VALUES (512, 'No Painting Like This', 12.5)]]></sql>
+		<sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) VALUES (512, 'No Painting Like This', 12.5)]]></sql>
+	</query>
+	<query name="ObjectQuery" type="SelectQuery" root="obj-entity" root-name="Painting">
+		<qualifier><![CDATA[toArtist = $artist]]></qualifier>
+		<ordering><![CDATA[paintingTitle]]></ordering>
+	</query>
+	<query name="ParameterizedNonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap-client">
+		<sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
+VALUES (#bind($id), #bind($title), #bind($price))]]></sql>
+		<sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) values (#bind($id), #bind($title), #bind($price))]]></sql>
+	</query>
+	<query name="ParameterizedQueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
+		<qualifier><![CDATA[artistName like $name]]></qualifier>
+	</query>
+	<query name="ParameterizedQueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
+		<qualifier><![CDATA[artistName like $name]]></qualifier>
+	</query>
+	<query name="ProcedureQuery" type="ProcedureQuery" root="procedure" root-name="cayenne_tst_select_proc" result-entity="Artist"/>
+	<query name="QueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
+	</query>
+	<query name="QueryWithOrdering" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<ordering descending="true" ignore-case="true"><![CDATA[artistName]]></ordering>
+		<ordering><![CDATA[dateOfBirth]]></ordering>
+	</query>
+	<query name="QueryWithPrefetch" type="SelectQuery" root="obj-entity" root-name="Gallery">
+		<prefetch>paintingArray</prefetch>
+	</query>
+	<query name="QueryWithQualifier" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<qualifier><![CDATA[artistName = $param1]]></qualifier>
+	</query>
+	<query name="QueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
+	</query>
+	<query name="SelectDateTest" type="SQLTemplate" root="data-map" root-name="testmap-client">
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<sql><![CDATA[SELECT * FROM DATE_TEST]]></sql>
+	</query>
+	<query name="SelectReturnTypesMap1" type="SQLTemplate" root="data-map" root-name="testmap-client">
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST1]]></sql>
+	</query>
+	<query name="SelectReturnTypesMap2" type="SQLTemplate" root="data-map" root-name="testmap-client">
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST2]]></sql>
+	</query>
+	<query name="SelectTestLower" type="SQLTemplate" root="data-map" root-name="testmap-client">
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="LOWER"/>
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<sql><![CDATA[select * from ARTIST]]></sql>
+	</query>
+	<query name="SelectTestUpper" type="SQLTemplate" root="data-map" root-name="testmap-client">
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<sql><![CDATA[select * from ARTIST]]></sql>
+	</query>
+</data-map>


[9/9] cayenne git commit: Merge remote-tracking branch 'remotes/parent/pr/265' into asf-master

Posted by nt...@apache.org.
Merge remote-tracking branch 'remotes/parent/pr/265' 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/750d3d55
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/750d3d55
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/750d3d55

Branch: refs/heads/master
Commit: 750d3d551913f5c8cb325f6075853627668e5f55
Parents: efee1d3 6378c41
Author: Nikita Timofeev <st...@gmail.com>
Authored: Mon Feb 5 12:28:29 2018 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Mon Feb 5 12:28:29 2018 +0300

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |   1 +
 itests/cayenne-tools-itest/pom.xml              | 178 -----
 .../tools/CayenneGeneratorIntegrationTest.java  | 186 -----
 .../src/test/resources/cayenne-client.xml       |   5 -
 .../src/test/resources/embeddable.map.xml       |  27 -
 .../apache/cayenne/tools/cgen-dependent.map.xml |  19 -
 .../org/apache/cayenne/tools/cgen.map.xml       |  15 -
 .../org/apache/cayenne/tools/velotemplate.vm    |  13 -
 .../src/test/resources/testmap-client.map.xml   | 730 ------------------
 .../src/test/resources/testmap.map.xml          | 735 -------------------
 itests/pom.xml                                  |  57 --
 maven-plugins/cayenne-tools-itest/pom.xml       | 178 +++++
 .../tools/CayenneGeneratorIntegrationTest.java  | 186 +++++
 .../src/test/resources/cayenne-client.xml       |   5 +
 .../src/test/resources/embeddable.map.xml       |  27 +
 .../apache/cayenne/tools/cgen-dependent.map.xml |  19 +
 .../org/apache/cayenne/tools/cgen.map.xml       |  15 +
 .../org/apache/cayenne/tools/velotemplate.vm    |  13 +
 .../src/test/resources/testmap-client.map.xml   | 730 ++++++++++++++++++
 .../src/test/resources/testmap.map.xml          | 735 +++++++++++++++++++
 maven-plugins/pom.xml                           |   8 +
 pom.xml                                         |   1 -
 22 files changed, 1917 insertions(+), 1966 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/750d3d55/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --cc RELEASE-NOTES.txt
index dbf604a,6ec11fb..37878eb
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@@ -21,7 -21,7 +21,8 @@@ CAY-2393 Add sqlserver-docker profile t
  CAY-2394 Upgrade to Apache Velocity 2.0
  CAY-2395 cdbimport: add option to create project file
  CAY-2396 Upgrade maven-assembly-plugin to 3.1.0
 +CAY-2403 Extract eventbridges to top level
+ CAY-2404 Move itests to maven-plugins
  
  Bug Fixes:
  

http://git-wip-us.apache.org/repos/asf/cayenne/blob/750d3d55/pom.xml
----------------------------------------------------------------------
diff --cc pom.xml
index 1c088e3,f405f96..e3a1199
--- a/pom.xml
+++ b/pom.xml
@@@ -70,10 -74,7 +70,9 @@@
  		<module>cayenne-web</module>
  		<module>cayenne-osgi</module>
  		<module>cayenne-rop-server</module>
 -		<module>eventbridges</module>
 +		<module>cayenne-jgroups</module>
 +		<module>cayenne-jms</module>
 +		<module>cayenne-xmpp</module>
- 		<module>itests</module>
  		<module>maven-plugins</module>
  		<module>modeler</module>
  		<module>tutorials</module>


[4/9] cayenne git commit: Merge remote-tracking branch 'remotes/parent/pr/264' into asf-master

Posted by nt...@apache.org.
Merge remote-tracking branch 'remotes/parent/pr/264' 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/efee1d3f
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/efee1d3f
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/efee1d3f

Branch: refs/heads/master
Commit: efee1d3fabd543d3a257162ab187b087147e9e3b
Parents: d8a944b ab1fd0b
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Feb 2 16:25:22 2018 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Feb 2 16:25:22 2018 +0300

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |   1 +
 cayenne-jgroups/pom.xml                         |  82 +++++
 .../org/apache/cayenne/event/JGroupsModule.java |  63 ++++
 .../event/JGroupsServerModuleProvider.java      |  50 +++
 .../apache/cayenne/event/JavaGroupsBridge.java  | 231 ++++++++++++++
 .../cayenne/event/JavaGroupsBridgeFactory.java  |  49 +++
 .../cayenne/event/JavaGroupsBridgeProvider.java |  50 +++
 ...iguration.server.CayenneServerModuleProvider |  20 ++
 .../event/CayenneJGroupsModuleProviderTest.java |  36 +++
 .../event/JavaGroupsBridgeFactoryTest.java      |  84 +++++
 .../event/JavaGroupsBridgeProviderTest.java     |  97 ++++++
 cayenne-jms/pom.xml                             |  81 +++++
 .../org/apache/cayenne/event/JMSBridge.java     | 280 +++++++++++++++++
 .../apache/cayenne/event/JMSBridgeFactory.java  |  39 +++
 .../apache/cayenne/event/JMSBridgeProvider.java |  50 +++
 .../org/apache/cayenne/event/JMSModule.java     |  54 ++++
 .../cayenne/event/JMSServerModuleProvider.java  |  50 +++
 ...iguration.server.CayenneServerModuleProvider |  20 ++
 .../event/CayenneJMSModuleProviderTest.java     |  36 +++
 .../cayenne/event/JMSBridgeFactoryTest.java     |  77 +++++
 .../cayenne/event/JMSBridgeProviderTest.java    |  87 ++++++
 cayenne-xmpp/pom.xml                            |  86 ++++++
 .../org/apache/cayenne/event/XMPPBridge.java    | 308 +++++++++++++++++++
 .../apache/cayenne/event/XMPPBridgeFactory.java |  41 +++
 .../cayenne/event/XMPPBridgeProvider.java       |  50 +++
 .../org/apache/cayenne/event/XMPPModule.java    |  71 +++++
 .../cayenne/event/XMPPServerModuleProvider.java |  50 +++
 ...iguration.server.CayenneServerModuleProvider |  20 ++
 .../event/CayenneXMPPModuleProviderTest.java    |  36 +++
 .../cayenne/event/XMPPBridgeFactoryTest.java    |  72 +++++
 .../cayenne/event/XMPPBridgeProviderTest.java   | 105 +++++++
 .../apache/cayenne/event/XMPPBridgeTest.java    |  54 ++++
 eventbridges/cayenne-jgroups/pom.xml            |  41 ---
 .../org/apache/cayenne/event/JGroupsModule.java |  63 ----
 .../event/JGroupsServerModuleProvider.java      |  50 ---
 .../apache/cayenne/event/JavaGroupsBridge.java  | 231 --------------
 .../cayenne/event/JavaGroupsBridgeFactory.java  |  49 ---
 .../cayenne/event/JavaGroupsBridgeProvider.java |  50 ---
 ...iguration.server.CayenneServerModuleProvider |  20 --
 .../event/CayenneJGroupsModuleProviderTest.java |  36 ---
 .../event/JavaGroupsBridgeFactoryTest.java      |  84 -----
 .../event/JavaGroupsBridgeProviderTest.java     |  97 ------
 eventbridges/cayenne-jms/pom.xml                |  41 ---
 .../org/apache/cayenne/event/JMSBridge.java     | 280 -----------------
 .../apache/cayenne/event/JMSBridgeFactory.java  |  39 ---
 .../apache/cayenne/event/JMSBridgeProvider.java |  50 ---
 .../org/apache/cayenne/event/JMSModule.java     |  54 ----
 .../cayenne/event/JMSServerModuleProvider.java  |  50 ---
 ...iguration.server.CayenneServerModuleProvider |  20 --
 .../event/CayenneJMSModuleProviderTest.java     |  36 ---
 .../cayenne/event/JMSBridgeFactoryTest.java     |  77 -----
 .../cayenne/event/JMSBridgeProviderTest.java    |  87 ------
 eventbridges/cayenne-xmpp/pom.xml               |  46 ---
 .../org/apache/cayenne/event/XMPPBridge.java    | 308 -------------------
 .../apache/cayenne/event/XMPPBridgeFactory.java |  41 ---
 .../cayenne/event/XMPPBridgeProvider.java       |  50 ---
 .../org/apache/cayenne/event/XMPPModule.java    |  71 -----
 .../cayenne/event/XMPPServerModuleProvider.java |  50 ---
 ...iguration.server.CayenneServerModuleProvider |  20 --
 .../event/CayenneXMPPModuleProviderTest.java    |  36 ---
 .../cayenne/event/XMPPBridgeFactoryTest.java    |  72 -----
 .../cayenne/event/XMPPBridgeProviderTest.java   | 105 -------
 .../apache/cayenne/event/XMPPBridgeTest.java    |  54 ----
 eventbridges/pom.xml                            |  82 -----
 pom.xml                                         |   4 +-
 65 files changed, 2433 insertions(+), 2391 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/efee1d3f/pom.xml
----------------------------------------------------------------------


[5/9] cayenne git commit: CAY-2404

Posted by nt...@apache.org.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/cayenne-tools-itest/src/test/resources/testmap.map.xml
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-tools-itest/src/test/resources/testmap.map.xml b/maven-plugins/cayenne-tools-itest/src/test/resources/testmap.map.xml
new file mode 100644
index 0000000..e426dda
--- /dev/null
+++ b/maven-plugins/cayenne-tools-itest/src/test/resources/testmap.map.xml
@@ -0,0 +1,735 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd"
+	 project-version="10">
+	<property name="defaultPackage" value="org.apache.cayenne.testdo.testmap"/>
+	<property name="defaultSuperclass" value="org.apache.cayenne.CayenneDataObject"/>
+	<property name="clientSupported" value="true"/>
+	<property name="defaultClientPackage" value="test.client"/>
+	<property name="defaultClientSuperclass" value="org.apache.cayenne.PersistentObject"/>
+	<procedure name="cayenne_tst_out_proc">
+		<procedure-parameter name="in_param" type="INTEGER" direction="in"/>
+		<procedure-parameter name="out_param" type="INTEGER" direction="out"/>
+	</procedure>
+	<procedure name="cayenne_tst_select_proc">
+		<procedure-parameter name="aName" type="VARCHAR" length="254" direction="in"/>
+		<procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
+	</procedure>
+	<procedure name="cayenne_tst_upd_proc">
+		<procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
+	</procedure>
+	<procedure name="cayenne_tst_upd_proc2">
+	</procedure>
+	<db-entity name="ARRAYS_ENTITY">
+		<db-attribute name="BYTE_ARRAY" type="VARBINARY" length="200"/>
+		<db-attribute name="BYTE_WRAPPER_ARRAY" type="VARBINARY" length="200"/>
+		<db-attribute name="CHAR_ARRAY" type="VARCHAR" length="200"/>
+		<db-attribute name="CHAR_WRAPPER_ARRAY" type="VARCHAR" length="200"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="ARTGROUP">
+		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" isMandatory="true" length="100"/>
+		<db-attribute name="PARENT_GROUP_ID" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="ARTIST">
+		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
+		<db-attribute name="DATE_OF_BIRTH" type="DATE"/>
+	</db-entity>
+	<db-entity name="ARTIST_CT">
+		<db-attribute name="ARTIST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
+		<db-attribute name="DATE_OF_BIRTH" type="DATE"/>
+	</db-entity>
+	<db-entity name="ARTIST_EXHIBIT">
+		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="ARTIST_GROUP">
+		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BIGDECIMAL_ENTITY">
+		<db-attribute name="BIGDECIMAL_FIELD" type="NUMERIC" length="12" scale="2"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BIGINTEGER_ENTITY">
+		<db-attribute name="BIG_INTEGER_FIELD" type="BIGINT"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BINARY_PK_TEST1">
+		<db-attribute name="BIN_ID" type="VARBINARY" isPrimaryKey="true" isMandatory="true" length="32"/>
+		<db-attribute name="NAME" type="VARCHAR" length="10"/>
+	</db-entity>
+	<db-entity name="BINARY_PK_TEST2">
+		<db-attribute name="DETAIL_NAME" type="VARCHAR" length="10"/>
+		<db-attribute name="FK_ID" type="VARBINARY" length="32"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BIT_TEST">
+		<db-attribute name="BIT_COLUMN" type="BIT" isMandatory="true"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BLOB_TEST">
+		<db-attribute name="BLOB_COL" type="BLOB"/>
+		<db-attribute name="BLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="BOOLEAN_TEST">
+		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN" isMandatory="true"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CALENDAR_TEST">
+		<db-attribute name="CALENDAR_FIELD" type="TIMESTAMP"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CHARACTER_ENTITY">
+		<db-attribute name="CHARACTER_FIELD" type="CHAR" length="1"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CHAR_FK_TEST">
+		<db-attribute name="FK_COL" type="CHAR" length="10"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+		<db-attribute name="PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CHAR_PK_TEST">
+		<db-attribute name="OTHER_COL" type="CHAR" length="10"/>
+		<db-attribute name="PK_COL" type="CHAR" isPrimaryKey="true" isMandatory="true" length="10"/>
+	</db-entity>
+	<db-entity name="CLOB_TEST">
+		<db-attribute name="CLOB_COL" type="CLOB"/>
+		<db-attribute name="CLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CLOB_TEST_RELATION">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="ID_CLOB" type="INTEGER" isMandatory="true"/>
+		<db-attribute name="VALUE" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="COMPOUND_FK_TEST">
+		<db-attribute name="F_KEY1" type="VARCHAR" length="20"/>
+		<db-attribute name="F_KEY2" type="VARCHAR" length="20"/>
+		<db-attribute name="NAME" type="VARCHAR" length="255"/>
+		<db-attribute name="PKEY" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="COMPOUND_PK_TEST">
+		<db-attribute name="KEY1" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
+		<db-attribute name="KEY2" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
+		<db-attribute name="NAME" type="VARCHAR" length="255"/>
+	</db-entity>
+	<db-entity name="DATE_TEST">
+		<db-attribute name="DATE_COLUMN" type="DATE"/>
+		<db-attribute name="DATE_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
+		<db-attribute name="TIME_COLUMN" type="TIME"/>
+	</db-entity>
+	<db-entity name="DECIMAL_PK_TST">
+		<db-attribute name="DECIMAL_PK" type="DECIMAL" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="ENUM_ENTITY">
+		<db-attribute name="ENUM_ATTRIBUTE" type="VARCHAR" length="250"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="EXHIBIT">
+		<db-attribute name="CLOSING_DATE" type="TIMESTAMP" isMandatory="true"/>
+		<db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="GALLERY_ID" type="INTEGER" isMandatory="true"/>
+		<db-attribute name="OPENING_DATE" type="TIMESTAMP" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="EXTENDED_TYPE_TEST">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="200"/>
+	</db-entity>
+	<db-entity name="FLOAT_TEST">
+		<db-attribute name="FLOAT_COL" type="FLOAT"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="GALLERY">
+		<db-attribute name="GALLERY_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="GALLERY_NAME" type="VARCHAR" isMandatory="true" length="100"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_COMP_KEY">
+		<db-attribute name="AUTO_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+		<db-attribute name="PROPAGATED_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_COMP_M">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_DEP">
+		<db-attribute name="GENERATED_COLUMN_FK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_TEST">
+		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="250"/>
+	</db-entity>
+	<db-entity name="GENERATED_COLUMN_TEST2">
+		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="GENERATED_F1">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="GENERATED_F2">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="GENERATED_JOIN">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+		<db-attribute name="ID1" type="INTEGER"/>
+		<db-attribute name="ID2" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="LONG_ENTITY">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="LONG_FIELD" type="BIGINT"/>
+	</db-entity>
+	<db-entity name="MEANINGFUL_PK_DEP">
+		<db-attribute name="DESCR" type="VARCHAR" length="50"/>
+		<db-attribute name="MASTER_PK" type="INTEGER"/>
+		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="MEANINGFUL_PK_TEST1">
+		<db-attribute name="DESCR" type="VARCHAR" length="50"/>
+		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="MIXED_PERSISTENCE_STRATEGY">
+		<db-attribute name="DESCRIPTION" type="VARCHAR" length="200"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="200"/>
+	</db-entity>
+	<db-entity name="MIXED_PERSISTENCE_STRATEGY2">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="MASTER_ID" type="INTEGER"/>
+		<db-attribute name="NAME" type="VARCHAR" length="200"/>
+	</db-entity>
+	<db-entity name="NO_PK_TEST">
+		<db-attribute name="ATTRIBUTE1" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="PAINTING">
+		<db-attribute name="ARTIST_ID" type="BIGINT"/>
+		<db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
+		<db-attribute name="GALLERY_ID" type="INTEGER"/>
+		<db-attribute name="PAINTING_DESCRIPTION" type="VARCHAR" length="255"/>
+		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
+	</db-entity>
+	<db-entity name="PAINTING1">
+		<db-attribute name="ARTIST_ID" type="BIGINT"/>
+		<db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
+		<db-attribute name="GALLERY_ID" type="INTEGER"/>
+		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
+	</db-entity>
+	<db-entity name="PAINTING_INFO">
+		<db-attribute name="IMAGE_BLOB" type="LONGVARBINARY"/>
+		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="TEXT_REVIEW" type="LONGVARCHAR"/>
+	</db-entity>
+	<db-entity name="PRIMITIVES_TEST">
+		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="INT_COLUMN" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="SERIALIZABLE_ENTITY">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="SERIALIZABLE_FIELD" type="BLOB"/>
+	</db-entity>
+	<db-entity name="SMALLINT_TEST">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="SMALLINT_COL" type="SMALLINT"/>
+	</db-entity>
+	<db-entity name="TINYINT_TEST">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="TINYINT_COL" type="TINYINT"/>
+	</db-entity>
+	<db-entity name="TYPES_MAPPING_TEST1">
+		<db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="BIGINT_COLUMN" type="BIGINT"/>
+		<db-attribute name="BIT_COLUMN" type="BIT"/>
+		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
+		<db-attribute name="CHAR_COLUMN" type="CHAR" length="254"/>
+		<db-attribute name="CLOB_COLUMN" type="CLOB"/>
+		<db-attribute name="DATE_COLUMN" type="DATE"/>
+		<db-attribute name="DECIMAL_COLUMN" type="DECIMAL" length="12" scale="5"/>
+		<db-attribute name="DOUBLE_COLUMN" type="DOUBLE" scale="7"/>
+		<db-attribute name="FLOAT_COLUMN" type="FLOAT" scale="3"/>
+		<db-attribute name="INTEGER_COLUMN" type="INTEGER"/>
+		<db-attribute name="LONGVARCHAR_COLUMN" type="LONGVARCHAR"/>
+		<db-attribute name="NUMERIC_COLUMN" type="NUMERIC" length="12" scale="5"/>
+		<db-attribute name="REAL_COLUMN" type="REAL" scale="5"/>
+		<db-attribute name="SMALLINT_COLUMN" type="SMALLINT"/>
+		<db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
+		<db-attribute name="TIME_COLUMN" type="TIME"/>
+		<db-attribute name="TINYINT_COLUMN" type="TINYINT"/>
+		<db-attribute name="VARCHAR_COLUMN" type="VARCHAR" length="255"/>
+	</db-entity>
+	<db-entity name="TYPES_MAPPING_TEST2">
+		<db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="BINARY_COLUMN" type="BINARY" length="14"/>
+		<db-attribute name="BLOB_COLUMN" type="BLOB"/>
+		<db-attribute name="LONGVARBINARY_COLUMN" type="LONGVARBINARY"/>
+		<db-attribute name="VARBINARY_COLUMN" type="VARBINARY" length="1000"/>
+	</db-entity>
+	<db-entity name="UUID_TEST">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="UUID" type="VARCHAR" length="100"/>
+	</db-entity>
+	<obj-entity name="ArraysEntity" className="org.apache.cayenne.testdo.misc_types.ArraysEntity" dbEntityName="ARRAYS_ENTITY">
+		<obj-attribute name="byteArray" type="byte[]" db-attribute-path="BYTE_ARRAY"/>
+		<obj-attribute name="byteWrapperArray" type="java.lang.Byte[]" db-attribute-path="BYTE_WRAPPER_ARRAY"/>
+		<obj-attribute name="charArray" type="char[]" db-attribute-path="CHAR_ARRAY"/>
+		<obj-attribute name="charWrapperArray" type="java.lang.Character[]" db-attribute-path="CHAR_WRAPPER_ARRAY"/>
+	</obj-entity>
+	<obj-entity name="ArtGroup" className="org.apache.cayenne.testdo.testmap.ArtGroup" dbEntityName="ARTGROUP">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="Artist" className="org.apache.cayenne.testdo.testmap.Artist" dbEntityName="ARTIST">
+		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
+		<obj-attribute name="dateOfBirth" type="java.util.Date" db-attribute-path="DATE_OF_BIRTH"/>
+	</obj-entity>
+	<obj-entity name="ArtistCallbackTest" className="org.apache.cayenne.testdo.testmap.ArtistCallbackTest" dbEntityName="ARTIST_CT">
+		<obj-attribute name="artistName" type="java.lang.String"/>
+		<obj-attribute name="dateOfBirth" type="java.util.Date"/>
+		<post-add method-name="prePersistEntityObjEntity"/>
+		<post-persist method-name="postPersistEntityObjEntity"/>
+		<pre-update method-name="preUpdateEntityObjEntity"/>
+		<post-update method-name="postUpdateEntityObjEntity"/>
+		<pre-remove method-name="preRemoveEntityObjEntity"/>
+		<post-remove method-name="postRemoveEntityObjEntity"/>
+		<post-load method-name="postLoadEntityObjEntity"/>
+	</obj-entity>
+	<obj-entity name="ArtistExhibit" className="org.apache.cayenne.testdo.testmap.ArtistExhibit" dbEntityName="ARTIST_EXHIBIT">
+	</obj-entity>
+	<obj-entity name="BigDecimalEntity" className="org.apache.cayenne.testdo.numeric_types.BigDecimalEntity" dbEntityName="BIGDECIMAL_ENTITY">
+		<obj-attribute name="bigDecimalField" type="java.math.BigDecimal" db-attribute-path="BIGDECIMAL_FIELD"/>
+	</obj-entity>
+	<obj-entity name="BigIntegerEntity" className="org.apache.cayenne.testdo.numeric_types.BigIntegerEntity" dbEntityName="BIGINTEGER_ENTITY">
+		<obj-attribute name="bigIntegerField" type="java.math.BigInteger" db-attribute-path="BIG_INTEGER_FIELD"/>
+	</obj-entity>
+	<obj-entity name="BinaryPKTest1" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest1" dbEntityName="BINARY_PK_TEST1">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="BinaryPKTest2" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest2" dbEntityName="BINARY_PK_TEST2">
+		<obj-attribute name="detailName" type="java.lang.String" db-attribute-path="DETAIL_NAME"/>
+	</obj-entity>
+	<obj-entity name="BitNumberTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitNumberTestEntity" dbEntityName="BIT_TEST">
+		<obj-attribute name="bitColumn" type="java.lang.Integer" db-attribute-path="BIT_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="BitTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitTestEntity" dbEntityName="BIT_TEST">
+		<obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="BlobTestEntity" className="org.apache.cayenne.testdo.lob.BlobTestEntity" dbEntityName="BLOB_TEST">
+		<obj-attribute name="blobCol" type="byte[]" db-attribute-path="BLOB_COL"/>
+	</obj-entity>
+	<obj-entity name="BooleanTestEntity" className="org.apache.cayenne.testdo.numeric_types.BooleanTestEntity" dbEntityName="BOOLEAN_TEST">
+		<obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="CalendarEntity" className="org.apache.cayenne.testdo.date_time.CalendarEntity" dbEntityName="CALENDAR_TEST">
+		<obj-attribute name="calendarField" type="java.util.Calendar" db-attribute-path="CALENDAR_FIELD"/>
+	</obj-entity>
+	<obj-entity name="CharFkTestEntity" className="org.apache.cayenne.testdo.compound.CharFkTestEntity" dbEntityName="CHAR_FK_TEST">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="CharPkTestEntity" className="org.apache.cayenne.testdo.compound.CharPkTestEntity" dbEntityName="CHAR_PK_TEST">
+		<obj-attribute name="otherCol" type="java.lang.String" db-attribute-path="OTHER_COL"/>
+		<obj-attribute name="pkCol" type="java.lang.String" db-attribute-path="PK_COL"/>
+	</obj-entity>
+	<obj-entity name="CharacterEntity" className="org.apache.cayenne.testdo.misc_types.CharacterEntity" dbEntityName="CHARACTER_ENTITY">
+		<obj-attribute name="characterField" type="java.lang.Character" db-attribute-path="CHARACTER_FIELD"/>
+	</obj-entity>
+	<obj-entity name="ClobTestEntity" className="org.apache.cayenne.testdo.lob.ClobTestEntity" dbEntityName="CLOB_TEST">
+		<obj-attribute name="clobCol" type="java.lang.String" db-attribute-path="CLOB_COL"/>
+	</obj-entity>
+	<obj-entity name="ClobTestRelation" className="org.apache.cayenne.testdo.lob.ClobTestRelation" dbEntityName="CLOB_TEST_RELATION">
+		<obj-attribute name="id" type="java.lang.Integer" db-attribute-path="ID"/>
+		<obj-attribute name="value" type="java.lang.Integer" db-attribute-path="VALUE"/>
+	</obj-entity>
+	<obj-entity name="CompoundFkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundFkTestEntity" dbEntityName="COMPOUND_FK_TEST">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="CompoundPainting" className="org.apache.cayenne.testdo.testmap.CompoundPainting" dbEntityName="PAINTING">
+		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="toArtist.ARTIST_NAME"/>
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="toGallery.GALLERY_NAME"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
+	</obj-entity>
+	<obj-entity name="CompoundPkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundPkTestEntity" dbEntityName="COMPOUND_PK_TEST">
+		<obj-attribute name="key1" type="java.lang.String" db-attribute-path="KEY1"/>
+		<obj-attribute name="key2" type="java.lang.String" db-attribute-path="KEY2"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="DateTestEntity" className="org.apache.cayenne.testdo.date_time.DateTestEntity" dbEntityName="DATE_TEST">
+		<obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
+		<obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
+		<obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="DecimalPKTest1" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTest1" dbEntityName="DECIMAL_PK_TST">
+		<obj-attribute name="decimalPK" type="java.lang.Double" db-attribute-path="DECIMAL_PK"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="DecimalPKTestEntity" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTestEntity" dbEntityName="DECIMAL_PK_TST">
+		<obj-attribute name="decimalPK" type="java.math.BigDecimal" db-attribute-path="DECIMAL_PK"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="EnumEntity" className="org.apache.cayenne.testdo.enum_test.EnumEntity" dbEntityName="ENUM_ENTITY">
+		<obj-attribute name="enumAttribute" type="org.apache.cayenne.testdo.enum_test.Enum1" db-attribute-path="ENUM_ATTRIBUTE"/>
+	</obj-entity>
+	<obj-entity name="Exhibit" className="org.apache.cayenne.testdo.testmap.Exhibit" dbEntityName="EXHIBIT">
+		<obj-attribute name="closingDate" type="java.util.Date" db-attribute-path="CLOSING_DATE"/>
+		<obj-attribute name="openingDate" type="java.util.Date" db-attribute-path="OPENING_DATE"/>
+	</obj-entity>
+	<obj-entity name="ExtendedTypeEntity" className="org.apache.cayenne.testdo.extended_type.ExtendedTypeEntity" dbEntityName="EXTENDED_TYPE_TEST">
+		<obj-attribute name="name" type="org.apache.cayenne.testdo.extended_type.StringET1" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="Gallery" className="org.apache.cayenne.testdo.testmap.Gallery" dbEntityName="GALLERY">
+		<obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="GALLERY_NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnCompKey" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompKey" dbEntityName="GENERATED_COLUMN_COMP_KEY">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnCompMaster" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompMaster" dbEntityName="GENERATED_COLUMN_COMP_M">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnDep" className="org.apache.cayenne.testdo.generated.GeneratedColumnDep" dbEntityName="GENERATED_COLUMN_DEP">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnTest2" className="org.apache.cayenne.testdo.generated.GeneratedColumnTest2" dbEntityName="GENERATED_COLUMN_TEST2">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedColumnTestEntity" className="org.apache.cayenne.testdo.generated.GeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="GeneratedF1" className="org.apache.cayenne.testdo.generated.GeneratedF1" clientClassName="test.client.GeneratedF1" dbEntityName="GENERATED_F1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+	</obj-entity>
+	<obj-entity name="GeneratedF2" className="org.apache.cayenne.testdo.generated.GeneratedF2" clientClassName="test.client.GeneratedF2" dbEntityName="GENERATED_F2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+	</obj-entity>
+	<obj-entity name="LongEntity" className="org.apache.cayenne.testdo.numeric_types.LongEntity" dbEntityName="LONG_ENTITY">
+		<obj-attribute name="longField" type="java.lang.Long" db-attribute-path="LONG_FIELD"/>
+	</obj-entity>
+	<obj-entity name="MeaningfulGeneratedColumnTestEntity" className="org.apache.cayenne.testdo.testmap.MeaningfulGeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
+		<obj-attribute name="generatedColumn" type="java.lang.Integer" db-attribute-path="GENERATED_COLUMN"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="MeaningfulPKDep" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKDep" dbEntityName="MEANINGFUL_PK_DEP">
+		<obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
+	</obj-entity>
+	<obj-entity name="MeaningfulPKTest1" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKTest1" dbEntityName="MEANINGFUL_PK_TEST1">
+		<obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
+		<obj-attribute name="pkAttribute" type="java.lang.Integer" db-attribute-path="PK_ATTRIBUTE"/>
+	</obj-entity>
+	<obj-entity name="MixedPersistenceStrategy" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy" dbEntityName="MIXED_PERSISTENCE_STRATEGY">
+		<obj-attribute name="description" type="java.lang.String" db-attribute-path="DESCRIPTION"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="MixedPersistenceStrategy2" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy2" dbEntityName="MIXED_PERSISTENCE_STRATEGY2">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="NoPkTestEntity" className="org.apache.cayenne.testdo.no_pk.NoPkTestEntity" dbEntityName="NO_PK_TEST">
+		<obj-attribute name="attribute1" type="java.lang.Integer" db-attribute-path="ATTRIBUTE1"/>
+	</obj-entity>
+	<obj-entity name="Painting" className="org.apache.cayenne.testdo.testmap.Painting" dbEntityName="PAINTING" superClassName="org.apache.cayenne.testdo.testmap.ArtDataObject">
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="paintingDescription" type="java.lang.String" db-attribute-path="PAINTING_DESCRIPTION"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+	</obj-entity>
+	<obj-entity name="Painting1" className="org.apache.cayenne.testdo.testmap.Painting1" dbEntityName="PAINTING1">
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+	</obj-entity>
+	<obj-entity name="PaintingInfo" className="org.apache.cayenne.testdo.testmap.PaintingInfo" dbEntityName="PAINTING_INFO">
+		<obj-attribute name="imageBlob" type="byte[]" db-attribute-path="IMAGE_BLOB"/>
+		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="TEXT_REVIEW"/>
+	</obj-entity>
+	<obj-entity name="PrimitivesTestEntity" className="org.apache.cayenne.testdo.primitive.PrimitivesTestEntity" dbEntityName="PRIMITIVES_TEST">
+		<obj-attribute name="booleanColumn" type="boolean" db-attribute-path="BOOLEAN_COLUMN"/>
+		<obj-attribute name="intColumn" type="int" db-attribute-path="INT_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="ROArtist" className="org.apache.cayenne.testdo.testmap.ROArtist" readOnly="true" dbEntityName="ARTIST">
+		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
+		<obj-attribute name="dateOfBirth" type="java.sql.Date" db-attribute-path="DATE_OF_BIRTH"/>
+	</obj-entity>
+	<obj-entity name="ROPainting" className="org.apache.cayenne.testdo.testmap.ROPainting" readOnly="true" dbEntityName="PAINTING">
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+	</obj-entity>
+	<obj-entity name="RWCompoundPainting" className="org.apache.cayenne.testdo.testmap.RWCompoundPainting" dbEntityName="PAINTING">
+		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
+	</obj-entity>
+	<obj-entity name="ReturnTypesMap1" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap1" clientClassName="test.client.ReturnTypesMap1" dbEntityName="TYPES_MAPPING_TEST1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+		<obj-attribute name="bigintColumn" type="java.lang.Long" db-attribute-path="BIGINT_COLUMN"/>
+		<obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
+		<obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
+		<obj-attribute name="charColumn" type="java.lang.String" db-attribute-path="CHAR_COLUMN"/>
+		<obj-attribute name="clobColumn" type="java.lang.String" db-attribute-path="CLOB_COLUMN"/>
+		<obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
+		<obj-attribute name="decimalColumn" type="java.math.BigDecimal" db-attribute-path="DECIMAL_COLUMN"/>
+		<obj-attribute name="doubleColumn" type="java.lang.Double" db-attribute-path="DOUBLE_COLUMN"/>
+		<obj-attribute name="floatColumn" type="java.lang.Float" db-attribute-path="FLOAT_COLUMN"/>
+		<obj-attribute name="integerColumn" type="java.lang.Integer" db-attribute-path="INTEGER_COLUMN"/>
+		<obj-attribute name="longvarcharColumn" type="java.lang.String" db-attribute-path="LONGVARCHAR_COLUMN"/>
+		<obj-attribute name="numericColumn" type="java.math.BigDecimal" db-attribute-path="NUMERIC_COLUMN"/>
+		<obj-attribute name="realColumn" type="java.lang.Float" db-attribute-path="REAL_COLUMN"/>
+		<obj-attribute name="smallintColumn" type="java.lang.Short" db-attribute-path="SMALLINT_COLUMN"/>
+		<obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
+		<obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
+		<obj-attribute name="tinyintColumn" type="java.lang.Byte" db-attribute-path="TINYINT_COLUMN"/>
+		<obj-attribute name="varcharColumn" type="java.lang.String" db-attribute-path="VARCHAR_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="ReturnTypesMap2" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap2" clientClassName="test.client.ReturnTypesMap2" dbEntityName="TYPES_MAPPING_TEST2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+		<obj-attribute name="binaryColumn" type="byte[]" db-attribute-path="BINARY_COLUMN"/>
+		<obj-attribute name="blobColumn" type="byte[]" db-attribute-path="BLOB_COLUMN"/>
+		<obj-attribute name="longvarbinaryColumn" type="byte[]" db-attribute-path="LONGVARBINARY_COLUMN"/>
+		<obj-attribute name="varbinaryColumn" type="byte[]" db-attribute-path="VARBINARY_COLUMN"/>
+	</obj-entity>
+	<obj-entity name="SerializableEntity" className="org.apache.cayenne.testdo.misc_types.SerializableEntity" dbEntityName="SERIALIZABLE_ENTITY">
+		<obj-attribute name="serializableField" type="org.apache.cayenne.MockSerializable" db-attribute-path="SERIALIZABLE_FIELD"/>
+	</obj-entity>
+	<obj-entity name="SmallintTestEntity" className="org.apache.cayenne.testdo.numeric_types.SmallintTestEntity" dbEntityName="SMALLINT_TEST">
+		<obj-attribute name="smallintCol" type="java.lang.Short" db-attribute-path="SMALLINT_COL"/>
+	</obj-entity>
+	<obj-entity name="SubPainting" className="org.apache.cayenne.testdo.testmap.SubPainting" dbEntityName="PAINTING">
+		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+	</obj-entity>
+	<obj-entity name="TinyintTestEntity" className="org.apache.cayenne.testdo.numeric_types.TinyintTestEntity" dbEntityName="TINYINT_TEST">
+		<obj-attribute name="tinyintCol" type="java.lang.Byte" db-attribute-path="TINYINT_COL"/>
+	</obj-entity>
+	<obj-entity name="UuidTestEntity" className="org.apache.cayenne.testdo.uuid.UuidTestEntity" dbEntityName="UUID_TEST">
+		<obj-attribute name="uuid" type="java.util.UUID" db-attribute-path="UUID"/>
+	</obj-entity>
+	<db-relationship name="artistGroupArray" source="ARTGROUP" target="ARTIST_GROUP" toMany="true">
+		<db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
+	</db-relationship>
+	<db-relationship name="toChildGroups" source="ARTGROUP" target="ARTGROUP" toMany="true">
+		<db-attribute-pair source="GROUP_ID" target="PARENT_GROUP_ID"/>
+	</db-relationship>
+	<db-relationship name="toParentGroup" source="ARTGROUP" target="ARTGROUP" toMany="false">
+		<db-attribute-pair source="PARENT_GROUP_ID" target="GROUP_ID"/>
+	</db-relationship>
+	<db-relationship name="artistExhibitArray" source="ARTIST" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="artistGroupArray" source="ARTIST" target="ARTIST_GROUP" toMany="true">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="paintingArray" source="ARTIST" target="PAINTING" toMany="true">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="toArtist" source="ARTIST_EXHIBIT" target="ARTIST" toMany="false">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="toExhibit" source="ARTIST_EXHIBIT" target="EXHIBIT" toMany="false">
+		<db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
+	</db-relationship>
+	<db-relationship name="toArtist" source="ARTIST_GROUP" target="ARTIST" toMany="false">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="toGroup" source="ARTIST_GROUP" target="ARTGROUP" toMany="false">
+		<db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
+	</db-relationship>
+	<db-relationship name="binaryPKDetails" source="BINARY_PK_TEST1" target="BINARY_PK_TEST2" toMany="true">
+		<db-attribute-pair source="BIN_ID" target="FK_ID"/>
+	</db-relationship>
+	<db-relationship name="toBinaryPKMaster" source="BINARY_PK_TEST2" target="BINARY_PK_TEST1" toMany="false">
+		<db-attribute-pair source="FK_ID" target="BIN_ID"/>
+	</db-relationship>
+	<db-relationship name="toCharPK" source="CHAR_FK_TEST" target="CHAR_PK_TEST" toMany="false">
+		<db-attribute-pair source="FK_COL" target="PK_COL"/>
+	</db-relationship>
+	<db-relationship name="charFKs" source="CHAR_PK_TEST" target="CHAR_FK_TEST" toMany="true">
+		<db-attribute-pair source="PK_COL" target="FK_COL"/>
+	</db-relationship>
+	<db-relationship name="clob" source="CLOB_TEST" target="CLOB_TEST_RELATION" toMany="true">
+		<db-attribute-pair source="CLOB_TEST_ID" target="ID_CLOB"/>
+	</db-relationship>
+	<db-relationship name="CLOB_REL" source="CLOB_TEST_RELATION" target="CLOB_TEST" toMany="false">
+		<db-attribute-pair source="ID_CLOB" target="CLOB_TEST_ID"/>
+	</db-relationship>
+	<db-relationship name="toCompoundPk" source="COMPOUND_FK_TEST" target="COMPOUND_PK_TEST" toMany="false">
+		<db-attribute-pair source="F_KEY1" target="KEY1"/>
+		<db-attribute-pair source="F_KEY2" target="KEY2"/>
+	</db-relationship>
+	<db-relationship name="compoundFkArray" source="COMPOUND_PK_TEST" target="COMPOUND_FK_TEST" toMany="true">
+		<db-attribute-pair source="KEY1" target="F_KEY1"/>
+		<db-attribute-pair source="KEY2" target="F_KEY2"/>
+	</db-relationship>
+	<db-relationship name="artistExhibitArray" source="EXHIBIT" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
+	</db-relationship>
+	<db-relationship name="toGallery" source="EXHIBIT" target="GALLERY" toMany="false">
+		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+	</db-relationship>
+	<db-relationship name="exhibitArray" source="GALLERY" target="EXHIBIT" toMany="true">
+		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+	</db-relationship>
+	<db-relationship name="paintingArray" source="GALLERY" target="PAINTING" toMany="true">
+		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+	</db-relationship>
+	<db-relationship name="toMaster" source="GENERATED_COLUMN_COMP_KEY" target="GENERATED_COLUMN_COMP_M" toMany="false">
+		<db-attribute-pair source="PROPAGATED_PK" target="ID"/>
+	</db-relationship>
+	<db-relationship name="toDetail" source="GENERATED_COLUMN_COMP_M" target="GENERATED_COLUMN_COMP_KEY" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="ID" target="PROPAGATED_PK"/>
+	</db-relationship>
+	<db-relationship name="toMaster" source="GENERATED_COLUMN_DEP" target="GENERATED_COLUMN_TEST" toMany="false">
+		<db-attribute-pair source="GENERATED_COLUMN_FK" target="GENERATED_COLUMN"/>
+	</db-relationship>
+	<db-relationship name="toDep" source="GENERATED_COLUMN_TEST" target="GENERATED_COLUMN_DEP" toDependentPK="true" toMany="false">
+		<db-attribute-pair source="GENERATED_COLUMN" target="GENERATED_COLUMN_FK"/>
+	</db-relationship>
+	<db-relationship name="join" source="GENERATED_F1" target="GENERATED_JOIN" toMany="true">
+		<db-attribute-pair source="ID" target="ID1"/>
+	</db-relationship>
+	<db-relationship name="join" source="GENERATED_F2" target="GENERATED_JOIN" toMany="true">
+		<db-attribute-pair source="ID" target="ID2"/>
+	</db-relationship>
+	<db-relationship name="f1" source="GENERATED_JOIN" target="GENERATED_F1" toMany="false">
+		<db-attribute-pair source="ID1" target="ID"/>
+	</db-relationship>
+	<db-relationship name="f2" source="GENERATED_JOIN" target="GENERATED_F2" toMany="false">
+		<db-attribute-pair source="ID2" target="ID"/>
+	</db-relationship>
+	<db-relationship name="toMeaningfulPK" source="MEANINGFUL_PK_DEP" target="MEANINGFUL_PK_TEST1" toMany="false">
+		<db-attribute-pair source="MASTER_PK" target="PK_ATTRIBUTE"/>
+	</db-relationship>
+	<db-relationship name="meaningfulPKDepArray" source="MEANINGFUL_PK_TEST1" target="MEANINGFUL_PK_DEP" toMany="true">
+		<db-attribute-pair source="PK_ATTRIBUTE" target="MASTER_PK"/>
+	</db-relationship>
+	<db-relationship name="details" source="MIXED_PERSISTENCE_STRATEGY" target="MIXED_PERSISTENCE_STRATEGY2" toMany="true">
+		<db-attribute-pair source="ID" target="MASTER_ID"/>
+	</db-relationship>
+	<db-relationship name="master" source="MIXED_PERSISTENCE_STRATEGY2" target="MIXED_PERSISTENCE_STRATEGY" toMany="false">
+		<db-attribute-pair source="MASTER_ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="toArtist" source="PAINTING" target="ARTIST" toMany="false">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="toGallery" source="PAINTING" target="GALLERY" toMany="false">
+		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+	</db-relationship>
+	<db-relationship name="toPaintingInfo" source="PAINTING" target="PAINTING_INFO" toDependentPK="true" toMany="false">
+		<db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
+	</db-relationship>
+	<db-relationship name="toArtist" source="PAINTING1" target="ARTIST" toMany="false">
+		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+	</db-relationship>
+	<db-relationship name="painting" source="PAINTING_INFO" target="PAINTING" toMany="false">
+		<db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
+	</db-relationship>
+	<obj-relationship name="artistArray" source="ArtGroup" target="Artist" deleteRule="Nullify" db-relationship-path="artistGroupArray.toArtist"/>
+	<obj-relationship name="childGroupsArray" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toChildGroups"/>
+	<obj-relationship name="toParentGroup" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toParentGroup"/>
+	<obj-relationship name="artistExhibitArray" source="Artist" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
+	<obj-relationship name="groupArray" source="Artist" target="ArtGroup" deleteRule="Cascade" db-relationship-path="artistGroupArray.toGroup"/>
+	<obj-relationship name="paintingArray" source="Artist" target="Painting" deleteRule="Cascade" db-relationship-path="paintingArray"/>
+	<obj-relationship name="toArtist" source="ArtistExhibit" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<obj-relationship name="toExhibit" source="ArtistExhibit" target="Exhibit" deleteRule="Nullify" db-relationship-path="toExhibit"/>
+	<obj-relationship name="binaryPKDetails" source="BinaryPKTest1" target="BinaryPKTest2" db-relationship-path="binaryPKDetails"/>
+	<obj-relationship name="toBinaryPKMaster" source="BinaryPKTest2" target="BinaryPKTest1" db-relationship-path="toBinaryPKMaster"/>
+	<obj-relationship name="toCharPK" source="CharFkTestEntity" target="CharPkTestEntity" db-relationship-path="toCharPK"/>
+	<obj-relationship name="charFKs" source="CharPkTestEntity" target="CharFkTestEntity" db-relationship-path="charFKs"/>
+	<obj-relationship name="clobValue" source="ClobTestEntity" target="ClobTestRelation" db-relationship-path="clob"/>
+	<obj-relationship name="clobId" source="ClobTestRelation" target="ClobTestEntity" db-relationship-path="CLOB_REL"/>
+	<obj-relationship name="toCompoundPk" source="CompoundFkTestEntity" target="CompoundPkTestEntity" db-relationship-path="toCompoundPk"/>
+	<obj-relationship name="toArtist" source="CompoundPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<obj-relationship name="toGallery" source="CompoundPainting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
+	<obj-relationship name="toPaintingInfo" source="CompoundPainting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
+	<obj-relationship name="compoundFkArray" source="CompoundPkTestEntity" target="CompoundFkTestEntity" db-relationship-path="compoundFkArray"/>
+	<obj-relationship name="artistExhibitArray" source="Exhibit" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
+	<obj-relationship name="toGallery" source="Exhibit" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
+	<obj-relationship name="exhibitArray" source="Gallery" target="Exhibit" deleteRule="Cascade" db-relationship-path="exhibitArray"/>
+	<obj-relationship name="paintingArray" source="Gallery" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
+	<obj-relationship name="toMaster" source="GeneratedColumnCompKey" target="GeneratedColumnCompMaster" db-relationship-path="toMaster"/>
+	<obj-relationship name="toDetail" source="GeneratedColumnCompMaster" target="GeneratedColumnCompKey" db-relationship-path="toDetail"/>
+	<obj-relationship name="toMaster" source="GeneratedColumnDep" target="GeneratedColumnTestEntity" db-relationship-path="toMaster"/>
+	<obj-relationship name="toDep" source="GeneratedColumnTestEntity" target="GeneratedColumnDep" db-relationship-path="toDep"/>
+	<obj-relationship name="f2" source="GeneratedF1" target="GeneratedF2" deleteRule="Nullify" db-relationship-path="join.f2"/>
+	<obj-relationship name="f1" source="GeneratedF2" target="GeneratedF1" deleteRule="Nullify" db-relationship-path="join.f1"/>
+	<obj-relationship name="toMeaningfulPK" source="MeaningfulPKDep" target="MeaningfulPKTest1" db-relationship-path="toMeaningfulPK"/>
+	<obj-relationship name="meaningfulPKDepArray" source="MeaningfulPKTest1" target="MeaningfulPKDep" db-relationship-path="meaningfulPKDepArray"/>
+	<obj-relationship name="details" source="MixedPersistenceStrategy" target="MixedPersistenceStrategy2" db-relationship-path="details"/>
+	<obj-relationship name="master" source="MixedPersistenceStrategy2" target="MixedPersistenceStrategy" db-relationship-path="master"/>
+	<obj-relationship name="toArtist" source="Painting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<obj-relationship name="toGallery" source="Painting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
+	<obj-relationship name="toPaintingInfo" source="Painting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
+	<obj-relationship name="toArtist" source="Painting1" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<obj-relationship name="painting" source="PaintingInfo" target="Painting" deleteRule="Nullify" db-relationship-path="painting"/>
+	<obj-relationship name="paintingArray" source="ROArtist" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
+	<obj-relationship name="toArtist" source="ROPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+	<query name="EjbqlQueryTest" type="EJBQLQuery">
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
+		<ejbql><![CDATA[select a from Artist a]]></ejbql>
+	</query>
+	<query name="NonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap">
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
+VALUES (512, 'No Painting Like This', 12.5)]]></sql>
+		<sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) VALUES (512, 'No Painting Like This', 12.5)]]></sql>
+	</query>
+	<query name="ObjectQuery" type="SelectQuery" root="obj-entity" root-name="Painting">
+		<qualifier><![CDATA[toArtist = $artist]]></qualifier>
+		<ordering><![CDATA[paintingTitle]]></ordering>
+	</query>
+	<query name="ParameterizedNonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap">
+		<sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
+VALUES (#bind($id), #bind($title), #bind($price))]]></sql>
+		<sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) values (#bind($id), #bind($title), #bind($price))]]></sql>
+	</query>
+	<query name="ParameterizedQueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
+		<qualifier><![CDATA[artistName like $name]]></qualifier>
+	</query>
+	<query name="ParameterizedQueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
+		<qualifier><![CDATA[artistName like $name]]></qualifier>
+	</query>
+	<query name="ProcedureQuery" type="ProcedureQuery" root="procedure" root-name="cayenne_tst_select_proc" result-entity="Artist">
+	</query>
+	<query name="QueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
+	</query>
+	<query name="QueryWithOrdering" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<ordering descending="true" ignore-case="true"><![CDATA[artistName]]></ordering>
+		<ordering><![CDATA[dateOfBirth]]></ordering>
+	</query>
+	<query name="QueryWithPrefetch" type="SelectQuery" root="obj-entity" root-name="Gallery">
+		<prefetch>paintingArray</prefetch>
+	</query>
+	<query name="QueryWithQualifier" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<qualifier><![CDATA[artistName = $param1]]></qualifier>
+	</query>
+	<query name="QueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
+	</query>
+	<query name="SelectDateTest" type="SQLTemplate" root="data-map" root-name="testmap">
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<sql><![CDATA[SELECT * FROM DATE_TEST]]></sql>
+	</query>
+	<query name="SelectReturnTypesMap1" type="SQLTemplate" root="data-map" root-name="testmap">
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST1]]></sql>
+	</query>
+	<query name="SelectReturnTypesMap2" type="SQLTemplate" root="data-map" root-name="testmap">
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST2]]></sql>
+	</query>
+	<query name="SelectTestLower" type="SQLTemplate" root="data-map" root-name="testmap">
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="LOWER"/>
+		<sql><![CDATA[select * from ARTIST]]></sql>
+	</query>
+	<query name="SelectTestUpper" type="SQLTemplate" root="data-map" root-name="testmap">
+		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+		<sql><![CDATA[select * from ARTIST]]></sql>
+	</query>
+</data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/pom.xml
----------------------------------------------------------------------
diff --git a/maven-plugins/pom.xml b/maven-plugins/pom.xml
index 22f2c84..15be022 100644
--- a/maven-plugins/pom.xml
+++ b/maven-plugins/pom.xml
@@ -25,6 +25,7 @@
 		<module>cayenne-maven-plugin</module>
 		<module>maven-cayenne-plugin</module>
 		<module>cayenne-modeler-maven-plugin</module>
+		<module>cayenne-tools-itest</module>
 	</modules>
 
 	<dependencyManagement>
@@ -111,6 +112,13 @@
 					</execution>
 				</executions>
 			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-deploy-plugin</artifactId>
+				<configuration>
+					<skip>true</skip>
+				</configuration>
+			</plugin>
 		</plugins>
 	</build>
 </project>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7444379..f405f96 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,6 @@
 		<module>cayenne-osgi</module>
 		<module>cayenne-rop-server</module>
 		<module>eventbridges</module>
-		<module>itests</module>
 		<module>maven-plugins</module>
 		<module>modeler</module>
 		<module>tutorials</module>


[7/9] cayenne git commit: CAY-2404

Posted by nt...@apache.org.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/cayenne-tools-itest/src/test/resources/testmap.map.xml
----------------------------------------------------------------------
diff --git a/itests/cayenne-tools-itest/src/test/resources/testmap.map.xml b/itests/cayenne-tools-itest/src/test/resources/testmap.map.xml
deleted file mode 100644
index e426dda..0000000
--- a/itests/cayenne-tools-itest/src/test/resources/testmap.map.xml
+++ /dev/null
@@ -1,735 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
-	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd"
-	 project-version="10">
-	<property name="defaultPackage" value="org.apache.cayenne.testdo.testmap"/>
-	<property name="defaultSuperclass" value="org.apache.cayenne.CayenneDataObject"/>
-	<property name="clientSupported" value="true"/>
-	<property name="defaultClientPackage" value="test.client"/>
-	<property name="defaultClientSuperclass" value="org.apache.cayenne.PersistentObject"/>
-	<procedure name="cayenne_tst_out_proc">
-		<procedure-parameter name="in_param" type="INTEGER" direction="in"/>
-		<procedure-parameter name="out_param" type="INTEGER" direction="out"/>
-	</procedure>
-	<procedure name="cayenne_tst_select_proc">
-		<procedure-parameter name="aName" type="VARCHAR" length="254" direction="in"/>
-		<procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
-	</procedure>
-	<procedure name="cayenne_tst_upd_proc">
-		<procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
-	</procedure>
-	<procedure name="cayenne_tst_upd_proc2">
-	</procedure>
-	<db-entity name="ARRAYS_ENTITY">
-		<db-attribute name="BYTE_ARRAY" type="VARBINARY" length="200"/>
-		<db-attribute name="BYTE_WRAPPER_ARRAY" type="VARBINARY" length="200"/>
-		<db-attribute name="CHAR_ARRAY" type="VARCHAR" length="200"/>
-		<db-attribute name="CHAR_WRAPPER_ARRAY" type="VARCHAR" length="200"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="ARTGROUP">
-		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" isMandatory="true" length="100"/>
-		<db-attribute name="PARENT_GROUP_ID" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="ARTIST">
-		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
-		<db-attribute name="DATE_OF_BIRTH" type="DATE"/>
-	</db-entity>
-	<db-entity name="ARTIST_CT">
-		<db-attribute name="ARTIST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
-		<db-attribute name="DATE_OF_BIRTH" type="DATE"/>
-	</db-entity>
-	<db-entity name="ARTIST_EXHIBIT">
-		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="ARTIST_GROUP">
-		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BIGDECIMAL_ENTITY">
-		<db-attribute name="BIGDECIMAL_FIELD" type="NUMERIC" length="12" scale="2"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BIGINTEGER_ENTITY">
-		<db-attribute name="BIG_INTEGER_FIELD" type="BIGINT"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BINARY_PK_TEST1">
-		<db-attribute name="BIN_ID" type="VARBINARY" isPrimaryKey="true" isMandatory="true" length="32"/>
-		<db-attribute name="NAME" type="VARCHAR" length="10"/>
-	</db-entity>
-	<db-entity name="BINARY_PK_TEST2">
-		<db-attribute name="DETAIL_NAME" type="VARCHAR" length="10"/>
-		<db-attribute name="FK_ID" type="VARBINARY" length="32"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BIT_TEST">
-		<db-attribute name="BIT_COLUMN" type="BIT" isMandatory="true"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BLOB_TEST">
-		<db-attribute name="BLOB_COL" type="BLOB"/>
-		<db-attribute name="BLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BOOLEAN_TEST">
-		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN" isMandatory="true"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CALENDAR_TEST">
-		<db-attribute name="CALENDAR_FIELD" type="TIMESTAMP"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CHARACTER_ENTITY">
-		<db-attribute name="CHARACTER_FIELD" type="CHAR" length="1"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CHAR_FK_TEST">
-		<db-attribute name="FK_COL" type="CHAR" length="10"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-		<db-attribute name="PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CHAR_PK_TEST">
-		<db-attribute name="OTHER_COL" type="CHAR" length="10"/>
-		<db-attribute name="PK_COL" type="CHAR" isPrimaryKey="true" isMandatory="true" length="10"/>
-	</db-entity>
-	<db-entity name="CLOB_TEST">
-		<db-attribute name="CLOB_COL" type="CLOB"/>
-		<db-attribute name="CLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CLOB_TEST_RELATION">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="ID_CLOB" type="INTEGER" isMandatory="true"/>
-		<db-attribute name="VALUE" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="COMPOUND_FK_TEST">
-		<db-attribute name="F_KEY1" type="VARCHAR" length="20"/>
-		<db-attribute name="F_KEY2" type="VARCHAR" length="20"/>
-		<db-attribute name="NAME" type="VARCHAR" length="255"/>
-		<db-attribute name="PKEY" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="COMPOUND_PK_TEST">
-		<db-attribute name="KEY1" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
-		<db-attribute name="KEY2" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
-		<db-attribute name="NAME" type="VARCHAR" length="255"/>
-	</db-entity>
-	<db-entity name="DATE_TEST">
-		<db-attribute name="DATE_COLUMN" type="DATE"/>
-		<db-attribute name="DATE_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
-		<db-attribute name="TIME_COLUMN" type="TIME"/>
-	</db-entity>
-	<db-entity name="DECIMAL_PK_TST">
-		<db-attribute name="DECIMAL_PK" type="DECIMAL" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-	</db-entity>
-	<db-entity name="ENUM_ENTITY">
-		<db-attribute name="ENUM_ATTRIBUTE" type="VARCHAR" length="250"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="EXHIBIT">
-		<db-attribute name="CLOSING_DATE" type="TIMESTAMP" isMandatory="true"/>
-		<db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="GALLERY_ID" type="INTEGER" isMandatory="true"/>
-		<db-attribute name="OPENING_DATE" type="TIMESTAMP" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="EXTENDED_TYPE_TEST">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="200"/>
-	</db-entity>
-	<db-entity name="FLOAT_TEST">
-		<db-attribute name="FLOAT_COL" type="FLOAT"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="GALLERY">
-		<db-attribute name="GALLERY_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="GALLERY_NAME" type="VARCHAR" isMandatory="true" length="100"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_COMP_KEY">
-		<db-attribute name="AUTO_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-		<db-attribute name="PROPAGATED_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_COMP_M">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_DEP">
-		<db-attribute name="GENERATED_COLUMN_FK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_TEST">
-		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="250"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_TEST2">
-		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-	</db-entity>
-	<db-entity name="GENERATED_F1">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="GENERATED_F2">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="GENERATED_JOIN">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
-		<db-attribute name="ID1" type="INTEGER"/>
-		<db-attribute name="ID2" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="LONG_ENTITY">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="LONG_FIELD" type="BIGINT"/>
-	</db-entity>
-	<db-entity name="MEANINGFUL_PK_DEP">
-		<db-attribute name="DESCR" type="VARCHAR" length="50"/>
-		<db-attribute name="MASTER_PK" type="INTEGER"/>
-		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="MEANINGFUL_PK_TEST1">
-		<db-attribute name="DESCR" type="VARCHAR" length="50"/>
-		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="MIXED_PERSISTENCE_STRATEGY">
-		<db-attribute name="DESCRIPTION" type="VARCHAR" length="200"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="200"/>
-	</db-entity>
-	<db-entity name="MIXED_PERSISTENCE_STRATEGY2">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="MASTER_ID" type="INTEGER"/>
-		<db-attribute name="NAME" type="VARCHAR" length="200"/>
-	</db-entity>
-	<db-entity name="NO_PK_TEST">
-		<db-attribute name="ATTRIBUTE1" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="PAINTING">
-		<db-attribute name="ARTIST_ID" type="BIGINT"/>
-		<db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
-		<db-attribute name="GALLERY_ID" type="INTEGER"/>
-		<db-attribute name="PAINTING_DESCRIPTION" type="VARCHAR" length="255"/>
-		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
-	</db-entity>
-	<db-entity name="PAINTING1">
-		<db-attribute name="ARTIST_ID" type="BIGINT"/>
-		<db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
-		<db-attribute name="GALLERY_ID" type="INTEGER"/>
-		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
-	</db-entity>
-	<db-entity name="PAINTING_INFO">
-		<db-attribute name="IMAGE_BLOB" type="LONGVARBINARY"/>
-		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="TEXT_REVIEW" type="LONGVARCHAR"/>
-	</db-entity>
-	<db-entity name="PRIMITIVES_TEST">
-		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="INT_COLUMN" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="SERIALIZABLE_ENTITY">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="SERIALIZABLE_FIELD" type="BLOB"/>
-	</db-entity>
-	<db-entity name="SMALLINT_TEST">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="SMALLINT_COL" type="SMALLINT"/>
-	</db-entity>
-	<db-entity name="TINYINT_TEST">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="TINYINT_COL" type="TINYINT"/>
-	</db-entity>
-	<db-entity name="TYPES_MAPPING_TEST1">
-		<db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="BIGINT_COLUMN" type="BIGINT"/>
-		<db-attribute name="BIT_COLUMN" type="BIT"/>
-		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
-		<db-attribute name="CHAR_COLUMN" type="CHAR" length="254"/>
-		<db-attribute name="CLOB_COLUMN" type="CLOB"/>
-		<db-attribute name="DATE_COLUMN" type="DATE"/>
-		<db-attribute name="DECIMAL_COLUMN" type="DECIMAL" length="12" scale="5"/>
-		<db-attribute name="DOUBLE_COLUMN" type="DOUBLE" scale="7"/>
-		<db-attribute name="FLOAT_COLUMN" type="FLOAT" scale="3"/>
-		<db-attribute name="INTEGER_COLUMN" type="INTEGER"/>
-		<db-attribute name="LONGVARCHAR_COLUMN" type="LONGVARCHAR"/>
-		<db-attribute name="NUMERIC_COLUMN" type="NUMERIC" length="12" scale="5"/>
-		<db-attribute name="REAL_COLUMN" type="REAL" scale="5"/>
-		<db-attribute name="SMALLINT_COLUMN" type="SMALLINT"/>
-		<db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
-		<db-attribute name="TIME_COLUMN" type="TIME"/>
-		<db-attribute name="TINYINT_COLUMN" type="TINYINT"/>
-		<db-attribute name="VARCHAR_COLUMN" type="VARCHAR" length="255"/>
-	</db-entity>
-	<db-entity name="TYPES_MAPPING_TEST2">
-		<db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="BINARY_COLUMN" type="BINARY" length="14"/>
-		<db-attribute name="BLOB_COLUMN" type="BLOB"/>
-		<db-attribute name="LONGVARBINARY_COLUMN" type="LONGVARBINARY"/>
-		<db-attribute name="VARBINARY_COLUMN" type="VARBINARY" length="1000"/>
-	</db-entity>
-	<db-entity name="UUID_TEST">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="UUID" type="VARCHAR" length="100"/>
-	</db-entity>
-	<obj-entity name="ArraysEntity" className="org.apache.cayenne.testdo.misc_types.ArraysEntity" dbEntityName="ARRAYS_ENTITY">
-		<obj-attribute name="byteArray" type="byte[]" db-attribute-path="BYTE_ARRAY"/>
-		<obj-attribute name="byteWrapperArray" type="java.lang.Byte[]" db-attribute-path="BYTE_WRAPPER_ARRAY"/>
-		<obj-attribute name="charArray" type="char[]" db-attribute-path="CHAR_ARRAY"/>
-		<obj-attribute name="charWrapperArray" type="java.lang.Character[]" db-attribute-path="CHAR_WRAPPER_ARRAY"/>
-	</obj-entity>
-	<obj-entity name="ArtGroup" className="org.apache.cayenne.testdo.testmap.ArtGroup" dbEntityName="ARTGROUP">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="Artist" className="org.apache.cayenne.testdo.testmap.Artist" dbEntityName="ARTIST">
-		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
-		<obj-attribute name="dateOfBirth" type="java.util.Date" db-attribute-path="DATE_OF_BIRTH"/>
-	</obj-entity>
-	<obj-entity name="ArtistCallbackTest" className="org.apache.cayenne.testdo.testmap.ArtistCallbackTest" dbEntityName="ARTIST_CT">
-		<obj-attribute name="artistName" type="java.lang.String"/>
-		<obj-attribute name="dateOfBirth" type="java.util.Date"/>
-		<post-add method-name="prePersistEntityObjEntity"/>
-		<post-persist method-name="postPersistEntityObjEntity"/>
-		<pre-update method-name="preUpdateEntityObjEntity"/>
-		<post-update method-name="postUpdateEntityObjEntity"/>
-		<pre-remove method-name="preRemoveEntityObjEntity"/>
-		<post-remove method-name="postRemoveEntityObjEntity"/>
-		<post-load method-name="postLoadEntityObjEntity"/>
-	</obj-entity>
-	<obj-entity name="ArtistExhibit" className="org.apache.cayenne.testdo.testmap.ArtistExhibit" dbEntityName="ARTIST_EXHIBIT">
-	</obj-entity>
-	<obj-entity name="BigDecimalEntity" className="org.apache.cayenne.testdo.numeric_types.BigDecimalEntity" dbEntityName="BIGDECIMAL_ENTITY">
-		<obj-attribute name="bigDecimalField" type="java.math.BigDecimal" db-attribute-path="BIGDECIMAL_FIELD"/>
-	</obj-entity>
-	<obj-entity name="BigIntegerEntity" className="org.apache.cayenne.testdo.numeric_types.BigIntegerEntity" dbEntityName="BIGINTEGER_ENTITY">
-		<obj-attribute name="bigIntegerField" type="java.math.BigInteger" db-attribute-path="BIG_INTEGER_FIELD"/>
-	</obj-entity>
-	<obj-entity name="BinaryPKTest1" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest1" dbEntityName="BINARY_PK_TEST1">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="BinaryPKTest2" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest2" dbEntityName="BINARY_PK_TEST2">
-		<obj-attribute name="detailName" type="java.lang.String" db-attribute-path="DETAIL_NAME"/>
-	</obj-entity>
-	<obj-entity name="BitNumberTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitNumberTestEntity" dbEntityName="BIT_TEST">
-		<obj-attribute name="bitColumn" type="java.lang.Integer" db-attribute-path="BIT_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="BitTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitTestEntity" dbEntityName="BIT_TEST">
-		<obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="BlobTestEntity" className="org.apache.cayenne.testdo.lob.BlobTestEntity" dbEntityName="BLOB_TEST">
-		<obj-attribute name="blobCol" type="byte[]" db-attribute-path="BLOB_COL"/>
-	</obj-entity>
-	<obj-entity name="BooleanTestEntity" className="org.apache.cayenne.testdo.numeric_types.BooleanTestEntity" dbEntityName="BOOLEAN_TEST">
-		<obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="CalendarEntity" className="org.apache.cayenne.testdo.date_time.CalendarEntity" dbEntityName="CALENDAR_TEST">
-		<obj-attribute name="calendarField" type="java.util.Calendar" db-attribute-path="CALENDAR_FIELD"/>
-	</obj-entity>
-	<obj-entity name="CharFkTestEntity" className="org.apache.cayenne.testdo.compound.CharFkTestEntity" dbEntityName="CHAR_FK_TEST">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="CharPkTestEntity" className="org.apache.cayenne.testdo.compound.CharPkTestEntity" dbEntityName="CHAR_PK_TEST">
-		<obj-attribute name="otherCol" type="java.lang.String" db-attribute-path="OTHER_COL"/>
-		<obj-attribute name="pkCol" type="java.lang.String" db-attribute-path="PK_COL"/>
-	</obj-entity>
-	<obj-entity name="CharacterEntity" className="org.apache.cayenne.testdo.misc_types.CharacterEntity" dbEntityName="CHARACTER_ENTITY">
-		<obj-attribute name="characterField" type="java.lang.Character" db-attribute-path="CHARACTER_FIELD"/>
-	</obj-entity>
-	<obj-entity name="ClobTestEntity" className="org.apache.cayenne.testdo.lob.ClobTestEntity" dbEntityName="CLOB_TEST">
-		<obj-attribute name="clobCol" type="java.lang.String" db-attribute-path="CLOB_COL"/>
-	</obj-entity>
-	<obj-entity name="ClobTestRelation" className="org.apache.cayenne.testdo.lob.ClobTestRelation" dbEntityName="CLOB_TEST_RELATION">
-		<obj-attribute name="id" type="java.lang.Integer" db-attribute-path="ID"/>
-		<obj-attribute name="value" type="java.lang.Integer" db-attribute-path="VALUE"/>
-	</obj-entity>
-	<obj-entity name="CompoundFkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundFkTestEntity" dbEntityName="COMPOUND_FK_TEST">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="CompoundPainting" className="org.apache.cayenne.testdo.testmap.CompoundPainting" dbEntityName="PAINTING">
-		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="toArtist.ARTIST_NAME"/>
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="toGallery.GALLERY_NAME"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
-	</obj-entity>
-	<obj-entity name="CompoundPkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundPkTestEntity" dbEntityName="COMPOUND_PK_TEST">
-		<obj-attribute name="key1" type="java.lang.String" db-attribute-path="KEY1"/>
-		<obj-attribute name="key2" type="java.lang.String" db-attribute-path="KEY2"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="DateTestEntity" className="org.apache.cayenne.testdo.date_time.DateTestEntity" dbEntityName="DATE_TEST">
-		<obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
-		<obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
-		<obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="DecimalPKTest1" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTest1" dbEntityName="DECIMAL_PK_TST">
-		<obj-attribute name="decimalPK" type="java.lang.Double" db-attribute-path="DECIMAL_PK"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="DecimalPKTestEntity" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTestEntity" dbEntityName="DECIMAL_PK_TST">
-		<obj-attribute name="decimalPK" type="java.math.BigDecimal" db-attribute-path="DECIMAL_PK"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="EnumEntity" className="org.apache.cayenne.testdo.enum_test.EnumEntity" dbEntityName="ENUM_ENTITY">
-		<obj-attribute name="enumAttribute" type="org.apache.cayenne.testdo.enum_test.Enum1" db-attribute-path="ENUM_ATTRIBUTE"/>
-	</obj-entity>
-	<obj-entity name="Exhibit" className="org.apache.cayenne.testdo.testmap.Exhibit" dbEntityName="EXHIBIT">
-		<obj-attribute name="closingDate" type="java.util.Date" db-attribute-path="CLOSING_DATE"/>
-		<obj-attribute name="openingDate" type="java.util.Date" db-attribute-path="OPENING_DATE"/>
-	</obj-entity>
-	<obj-entity name="ExtendedTypeEntity" className="org.apache.cayenne.testdo.extended_type.ExtendedTypeEntity" dbEntityName="EXTENDED_TYPE_TEST">
-		<obj-attribute name="name" type="org.apache.cayenne.testdo.extended_type.StringET1" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="Gallery" className="org.apache.cayenne.testdo.testmap.Gallery" dbEntityName="GALLERY">
-		<obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="GALLERY_NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnCompKey" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompKey" dbEntityName="GENERATED_COLUMN_COMP_KEY">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnCompMaster" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompMaster" dbEntityName="GENERATED_COLUMN_COMP_M">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnDep" className="org.apache.cayenne.testdo.generated.GeneratedColumnDep" dbEntityName="GENERATED_COLUMN_DEP">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnTest2" className="org.apache.cayenne.testdo.generated.GeneratedColumnTest2" dbEntityName="GENERATED_COLUMN_TEST2">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnTestEntity" className="org.apache.cayenne.testdo.generated.GeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedF1" className="org.apache.cayenne.testdo.generated.GeneratedF1" clientClassName="test.client.GeneratedF1" dbEntityName="GENERATED_F1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
-	</obj-entity>
-	<obj-entity name="GeneratedF2" className="org.apache.cayenne.testdo.generated.GeneratedF2" clientClassName="test.client.GeneratedF2" dbEntityName="GENERATED_F2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
-	</obj-entity>
-	<obj-entity name="LongEntity" className="org.apache.cayenne.testdo.numeric_types.LongEntity" dbEntityName="LONG_ENTITY">
-		<obj-attribute name="longField" type="java.lang.Long" db-attribute-path="LONG_FIELD"/>
-	</obj-entity>
-	<obj-entity name="MeaningfulGeneratedColumnTestEntity" className="org.apache.cayenne.testdo.testmap.MeaningfulGeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
-		<obj-attribute name="generatedColumn" type="java.lang.Integer" db-attribute-path="GENERATED_COLUMN"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="MeaningfulPKDep" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKDep" dbEntityName="MEANINGFUL_PK_DEP">
-		<obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
-	</obj-entity>
-	<obj-entity name="MeaningfulPKTest1" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKTest1" dbEntityName="MEANINGFUL_PK_TEST1">
-		<obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
-		<obj-attribute name="pkAttribute" type="java.lang.Integer" db-attribute-path="PK_ATTRIBUTE"/>
-	</obj-entity>
-	<obj-entity name="MixedPersistenceStrategy" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy" dbEntityName="MIXED_PERSISTENCE_STRATEGY">
-		<obj-attribute name="description" type="java.lang.String" db-attribute-path="DESCRIPTION"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="MixedPersistenceStrategy2" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy2" dbEntityName="MIXED_PERSISTENCE_STRATEGY2">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="NoPkTestEntity" className="org.apache.cayenne.testdo.no_pk.NoPkTestEntity" dbEntityName="NO_PK_TEST">
-		<obj-attribute name="attribute1" type="java.lang.Integer" db-attribute-path="ATTRIBUTE1"/>
-	</obj-entity>
-	<obj-entity name="Painting" className="org.apache.cayenne.testdo.testmap.Painting" dbEntityName="PAINTING" superClassName="org.apache.cayenne.testdo.testmap.ArtDataObject">
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="paintingDescription" type="java.lang.String" db-attribute-path="PAINTING_DESCRIPTION"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-	</obj-entity>
-	<obj-entity name="Painting1" className="org.apache.cayenne.testdo.testmap.Painting1" dbEntityName="PAINTING1">
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-	</obj-entity>
-	<obj-entity name="PaintingInfo" className="org.apache.cayenne.testdo.testmap.PaintingInfo" dbEntityName="PAINTING_INFO">
-		<obj-attribute name="imageBlob" type="byte[]" db-attribute-path="IMAGE_BLOB"/>
-		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="TEXT_REVIEW"/>
-	</obj-entity>
-	<obj-entity name="PrimitivesTestEntity" className="org.apache.cayenne.testdo.primitive.PrimitivesTestEntity" dbEntityName="PRIMITIVES_TEST">
-		<obj-attribute name="booleanColumn" type="boolean" db-attribute-path="BOOLEAN_COLUMN"/>
-		<obj-attribute name="intColumn" type="int" db-attribute-path="INT_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="ROArtist" className="org.apache.cayenne.testdo.testmap.ROArtist" readOnly="true" dbEntityName="ARTIST">
-		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
-		<obj-attribute name="dateOfBirth" type="java.sql.Date" db-attribute-path="DATE_OF_BIRTH"/>
-	</obj-entity>
-	<obj-entity name="ROPainting" className="org.apache.cayenne.testdo.testmap.ROPainting" readOnly="true" dbEntityName="PAINTING">
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-	</obj-entity>
-	<obj-entity name="RWCompoundPainting" className="org.apache.cayenne.testdo.testmap.RWCompoundPainting" dbEntityName="PAINTING">
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
-	</obj-entity>
-	<obj-entity name="ReturnTypesMap1" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap1" clientClassName="test.client.ReturnTypesMap1" dbEntityName="TYPES_MAPPING_TEST1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
-		<obj-attribute name="bigintColumn" type="java.lang.Long" db-attribute-path="BIGINT_COLUMN"/>
-		<obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
-		<obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
-		<obj-attribute name="charColumn" type="java.lang.String" db-attribute-path="CHAR_COLUMN"/>
-		<obj-attribute name="clobColumn" type="java.lang.String" db-attribute-path="CLOB_COLUMN"/>
-		<obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
-		<obj-attribute name="decimalColumn" type="java.math.BigDecimal" db-attribute-path="DECIMAL_COLUMN"/>
-		<obj-attribute name="doubleColumn" type="java.lang.Double" db-attribute-path="DOUBLE_COLUMN"/>
-		<obj-attribute name="floatColumn" type="java.lang.Float" db-attribute-path="FLOAT_COLUMN"/>
-		<obj-attribute name="integerColumn" type="java.lang.Integer" db-attribute-path="INTEGER_COLUMN"/>
-		<obj-attribute name="longvarcharColumn" type="java.lang.String" db-attribute-path="LONGVARCHAR_COLUMN"/>
-		<obj-attribute name="numericColumn" type="java.math.BigDecimal" db-attribute-path="NUMERIC_COLUMN"/>
-		<obj-attribute name="realColumn" type="java.lang.Float" db-attribute-path="REAL_COLUMN"/>
-		<obj-attribute name="smallintColumn" type="java.lang.Short" db-attribute-path="SMALLINT_COLUMN"/>
-		<obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
-		<obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
-		<obj-attribute name="tinyintColumn" type="java.lang.Byte" db-attribute-path="TINYINT_COLUMN"/>
-		<obj-attribute name="varcharColumn" type="java.lang.String" db-attribute-path="VARCHAR_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="ReturnTypesMap2" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap2" clientClassName="test.client.ReturnTypesMap2" dbEntityName="TYPES_MAPPING_TEST2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
-		<obj-attribute name="binaryColumn" type="byte[]" db-attribute-path="BINARY_COLUMN"/>
-		<obj-attribute name="blobColumn" type="byte[]" db-attribute-path="BLOB_COLUMN"/>
-		<obj-attribute name="longvarbinaryColumn" type="byte[]" db-attribute-path="LONGVARBINARY_COLUMN"/>
-		<obj-attribute name="varbinaryColumn" type="byte[]" db-attribute-path="VARBINARY_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="SerializableEntity" className="org.apache.cayenne.testdo.misc_types.SerializableEntity" dbEntityName="SERIALIZABLE_ENTITY">
-		<obj-attribute name="serializableField" type="org.apache.cayenne.MockSerializable" db-attribute-path="SERIALIZABLE_FIELD"/>
-	</obj-entity>
-	<obj-entity name="SmallintTestEntity" className="org.apache.cayenne.testdo.numeric_types.SmallintTestEntity" dbEntityName="SMALLINT_TEST">
-		<obj-attribute name="smallintCol" type="java.lang.Short" db-attribute-path="SMALLINT_COL"/>
-	</obj-entity>
-	<obj-entity name="SubPainting" className="org.apache.cayenne.testdo.testmap.SubPainting" dbEntityName="PAINTING">
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-	</obj-entity>
-	<obj-entity name="TinyintTestEntity" className="org.apache.cayenne.testdo.numeric_types.TinyintTestEntity" dbEntityName="TINYINT_TEST">
-		<obj-attribute name="tinyintCol" type="java.lang.Byte" db-attribute-path="TINYINT_COL"/>
-	</obj-entity>
-	<obj-entity name="UuidTestEntity" className="org.apache.cayenne.testdo.uuid.UuidTestEntity" dbEntityName="UUID_TEST">
-		<obj-attribute name="uuid" type="java.util.UUID" db-attribute-path="UUID"/>
-	</obj-entity>
-	<db-relationship name="artistGroupArray" source="ARTGROUP" target="ARTIST_GROUP" toMany="true">
-		<db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
-	</db-relationship>
-	<db-relationship name="toChildGroups" source="ARTGROUP" target="ARTGROUP" toMany="true">
-		<db-attribute-pair source="GROUP_ID" target="PARENT_GROUP_ID"/>
-	</db-relationship>
-	<db-relationship name="toParentGroup" source="ARTGROUP" target="ARTGROUP" toMany="false">
-		<db-attribute-pair source="PARENT_GROUP_ID" target="GROUP_ID"/>
-	</db-relationship>
-	<db-relationship name="artistExhibitArray" source="ARTIST" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="artistGroupArray" source="ARTIST" target="ARTIST_GROUP" toMany="true">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="paintingArray" source="ARTIST" target="PAINTING" toMany="true">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="toArtist" source="ARTIST_EXHIBIT" target="ARTIST" toMany="false">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="toExhibit" source="ARTIST_EXHIBIT" target="EXHIBIT" toMany="false">
-		<db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
-	</db-relationship>
-	<db-relationship name="toArtist" source="ARTIST_GROUP" target="ARTIST" toMany="false">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="toGroup" source="ARTIST_GROUP" target="ARTGROUP" toMany="false">
-		<db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
-	</db-relationship>
-	<db-relationship name="binaryPKDetails" source="BINARY_PK_TEST1" target="BINARY_PK_TEST2" toMany="true">
-		<db-attribute-pair source="BIN_ID" target="FK_ID"/>
-	</db-relationship>
-	<db-relationship name="toBinaryPKMaster" source="BINARY_PK_TEST2" target="BINARY_PK_TEST1" toMany="false">
-		<db-attribute-pair source="FK_ID" target="BIN_ID"/>
-	</db-relationship>
-	<db-relationship name="toCharPK" source="CHAR_FK_TEST" target="CHAR_PK_TEST" toMany="false">
-		<db-attribute-pair source="FK_COL" target="PK_COL"/>
-	</db-relationship>
-	<db-relationship name="charFKs" source="CHAR_PK_TEST" target="CHAR_FK_TEST" toMany="true">
-		<db-attribute-pair source="PK_COL" target="FK_COL"/>
-	</db-relationship>
-	<db-relationship name="clob" source="CLOB_TEST" target="CLOB_TEST_RELATION" toMany="true">
-		<db-attribute-pair source="CLOB_TEST_ID" target="ID_CLOB"/>
-	</db-relationship>
-	<db-relationship name="CLOB_REL" source="CLOB_TEST_RELATION" target="CLOB_TEST" toMany="false">
-		<db-attribute-pair source="ID_CLOB" target="CLOB_TEST_ID"/>
-	</db-relationship>
-	<db-relationship name="toCompoundPk" source="COMPOUND_FK_TEST" target="COMPOUND_PK_TEST" toMany="false">
-		<db-attribute-pair source="F_KEY1" target="KEY1"/>
-		<db-attribute-pair source="F_KEY2" target="KEY2"/>
-	</db-relationship>
-	<db-relationship name="compoundFkArray" source="COMPOUND_PK_TEST" target="COMPOUND_FK_TEST" toMany="true">
-		<db-attribute-pair source="KEY1" target="F_KEY1"/>
-		<db-attribute-pair source="KEY2" target="F_KEY2"/>
-	</db-relationship>
-	<db-relationship name="artistExhibitArray" source="EXHIBIT" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
-		<db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
-	</db-relationship>
-	<db-relationship name="toGallery" source="EXHIBIT" target="GALLERY" toMany="false">
-		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
-	</db-relationship>
-	<db-relationship name="exhibitArray" source="GALLERY" target="EXHIBIT" toMany="true">
-		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
-	</db-relationship>
-	<db-relationship name="paintingArray" source="GALLERY" target="PAINTING" toMany="true">
-		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
-	</db-relationship>
-	<db-relationship name="toMaster" source="GENERATED_COLUMN_COMP_KEY" target="GENERATED_COLUMN_COMP_M" toMany="false">
-		<db-attribute-pair source="PROPAGATED_PK" target="ID"/>
-	</db-relationship>
-	<db-relationship name="toDetail" source="GENERATED_COLUMN_COMP_M" target="GENERATED_COLUMN_COMP_KEY" toDependentPK="true" toMany="true">
-		<db-attribute-pair source="ID" target="PROPAGATED_PK"/>
-	</db-relationship>
-	<db-relationship name="toMaster" source="GENERATED_COLUMN_DEP" target="GENERATED_COLUMN_TEST" toMany="false">
-		<db-attribute-pair source="GENERATED_COLUMN_FK" target="GENERATED_COLUMN"/>
-	</db-relationship>
-	<db-relationship name="toDep" source="GENERATED_COLUMN_TEST" target="GENERATED_COLUMN_DEP" toDependentPK="true" toMany="false">
-		<db-attribute-pair source="GENERATED_COLUMN" target="GENERATED_COLUMN_FK"/>
-	</db-relationship>
-	<db-relationship name="join" source="GENERATED_F1" target="GENERATED_JOIN" toMany="true">
-		<db-attribute-pair source="ID" target="ID1"/>
-	</db-relationship>
-	<db-relationship name="join" source="GENERATED_F2" target="GENERATED_JOIN" toMany="true">
-		<db-attribute-pair source="ID" target="ID2"/>
-	</db-relationship>
-	<db-relationship name="f1" source="GENERATED_JOIN" target="GENERATED_F1" toMany="false">
-		<db-attribute-pair source="ID1" target="ID"/>
-	</db-relationship>
-	<db-relationship name="f2" source="GENERATED_JOIN" target="GENERATED_F2" toMany="false">
-		<db-attribute-pair source="ID2" target="ID"/>
-	</db-relationship>
-	<db-relationship name="toMeaningfulPK" source="MEANINGFUL_PK_DEP" target="MEANINGFUL_PK_TEST1" toMany="false">
-		<db-attribute-pair source="MASTER_PK" target="PK_ATTRIBUTE"/>
-	</db-relationship>
-	<db-relationship name="meaningfulPKDepArray" source="MEANINGFUL_PK_TEST1" target="MEANINGFUL_PK_DEP" toMany="true">
-		<db-attribute-pair source="PK_ATTRIBUTE" target="MASTER_PK"/>
-	</db-relationship>
-	<db-relationship name="details" source="MIXED_PERSISTENCE_STRATEGY" target="MIXED_PERSISTENCE_STRATEGY2" toMany="true">
-		<db-attribute-pair source="ID" target="MASTER_ID"/>
-	</db-relationship>
-	<db-relationship name="master" source="MIXED_PERSISTENCE_STRATEGY2" target="MIXED_PERSISTENCE_STRATEGY" toMany="false">
-		<db-attribute-pair source="MASTER_ID" target="ID"/>
-	</db-relationship>
-	<db-relationship name="toArtist" source="PAINTING" target="ARTIST" toMany="false">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="toGallery" source="PAINTING" target="GALLERY" toMany="false">
-		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
-	</db-relationship>
-	<db-relationship name="toPaintingInfo" source="PAINTING" target="PAINTING_INFO" toDependentPK="true" toMany="false">
-		<db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
-	</db-relationship>
-	<db-relationship name="toArtist" source="PAINTING1" target="ARTIST" toMany="false">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="painting" source="PAINTING_INFO" target="PAINTING" toMany="false">
-		<db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
-	</db-relationship>
-	<obj-relationship name="artistArray" source="ArtGroup" target="Artist" deleteRule="Nullify" db-relationship-path="artistGroupArray.toArtist"/>
-	<obj-relationship name="childGroupsArray" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toChildGroups"/>
-	<obj-relationship name="toParentGroup" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toParentGroup"/>
-	<obj-relationship name="artistExhibitArray" source="Artist" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
-	<obj-relationship name="groupArray" source="Artist" target="ArtGroup" deleteRule="Cascade" db-relationship-path="artistGroupArray.toGroup"/>
-	<obj-relationship name="paintingArray" source="Artist" target="Painting" deleteRule="Cascade" db-relationship-path="paintingArray"/>
-	<obj-relationship name="toArtist" source="ArtistExhibit" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<obj-relationship name="toExhibit" source="ArtistExhibit" target="Exhibit" deleteRule="Nullify" db-relationship-path="toExhibit"/>
-	<obj-relationship name="binaryPKDetails" source="BinaryPKTest1" target="BinaryPKTest2" db-relationship-path="binaryPKDetails"/>
-	<obj-relationship name="toBinaryPKMaster" source="BinaryPKTest2" target="BinaryPKTest1" db-relationship-path="toBinaryPKMaster"/>
-	<obj-relationship name="toCharPK" source="CharFkTestEntity" target="CharPkTestEntity" db-relationship-path="toCharPK"/>
-	<obj-relationship name="charFKs" source="CharPkTestEntity" target="CharFkTestEntity" db-relationship-path="charFKs"/>
-	<obj-relationship name="clobValue" source="ClobTestEntity" target="ClobTestRelation" db-relationship-path="clob"/>
-	<obj-relationship name="clobId" source="ClobTestRelation" target="ClobTestEntity" db-relationship-path="CLOB_REL"/>
-	<obj-relationship name="toCompoundPk" source="CompoundFkTestEntity" target="CompoundPkTestEntity" db-relationship-path="toCompoundPk"/>
-	<obj-relationship name="toArtist" source="CompoundPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<obj-relationship name="toGallery" source="CompoundPainting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
-	<obj-relationship name="toPaintingInfo" source="CompoundPainting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
-	<obj-relationship name="compoundFkArray" source="CompoundPkTestEntity" target="CompoundFkTestEntity" db-relationship-path="compoundFkArray"/>
-	<obj-relationship name="artistExhibitArray" source="Exhibit" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
-	<obj-relationship name="toGallery" source="Exhibit" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
-	<obj-relationship name="exhibitArray" source="Gallery" target="Exhibit" deleteRule="Cascade" db-relationship-path="exhibitArray"/>
-	<obj-relationship name="paintingArray" source="Gallery" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
-	<obj-relationship name="toMaster" source="GeneratedColumnCompKey" target="GeneratedColumnCompMaster" db-relationship-path="toMaster"/>
-	<obj-relationship name="toDetail" source="GeneratedColumnCompMaster" target="GeneratedColumnCompKey" db-relationship-path="toDetail"/>
-	<obj-relationship name="toMaster" source="GeneratedColumnDep" target="GeneratedColumnTestEntity" db-relationship-path="toMaster"/>
-	<obj-relationship name="toDep" source="GeneratedColumnTestEntity" target="GeneratedColumnDep" db-relationship-path="toDep"/>
-	<obj-relationship name="f2" source="GeneratedF1" target="GeneratedF2" deleteRule="Nullify" db-relationship-path="join.f2"/>
-	<obj-relationship name="f1" source="GeneratedF2" target="GeneratedF1" deleteRule="Nullify" db-relationship-path="join.f1"/>
-	<obj-relationship name="toMeaningfulPK" source="MeaningfulPKDep" target="MeaningfulPKTest1" db-relationship-path="toMeaningfulPK"/>
-	<obj-relationship name="meaningfulPKDepArray" source="MeaningfulPKTest1" target="MeaningfulPKDep" db-relationship-path="meaningfulPKDepArray"/>
-	<obj-relationship name="details" source="MixedPersistenceStrategy" target="MixedPersistenceStrategy2" db-relationship-path="details"/>
-	<obj-relationship name="master" source="MixedPersistenceStrategy2" target="MixedPersistenceStrategy" db-relationship-path="master"/>
-	<obj-relationship name="toArtist" source="Painting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<obj-relationship name="toGallery" source="Painting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
-	<obj-relationship name="toPaintingInfo" source="Painting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
-	<obj-relationship name="toArtist" source="Painting1" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<obj-relationship name="painting" source="PaintingInfo" target="Painting" deleteRule="Nullify" db-relationship-path="painting"/>
-	<obj-relationship name="paintingArray" source="ROArtist" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
-	<obj-relationship name="toArtist" source="ROPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<query name="EjbqlQueryTest" type="EJBQLQuery">
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
-		<ejbql><![CDATA[select a from Artist a]]></ejbql>
-	</query>
-	<query name="NonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap">
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
-VALUES (512, 'No Painting Like This', 12.5)]]></sql>
-		<sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) VALUES (512, 'No Painting Like This', 12.5)]]></sql>
-	</query>
-	<query name="ObjectQuery" type="SelectQuery" root="obj-entity" root-name="Painting">
-		<qualifier><![CDATA[toArtist = $artist]]></qualifier>
-		<ordering><![CDATA[paintingTitle]]></ordering>
-	</query>
-	<query name="ParameterizedNonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap">
-		<sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
-VALUES (#bind($id), #bind($title), #bind($price))]]></sql>
-		<sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) values (#bind($id), #bind($title), #bind($price))]]></sql>
-	</query>
-	<query name="ParameterizedQueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
-		<qualifier><![CDATA[artistName like $name]]></qualifier>
-	</query>
-	<query name="ParameterizedQueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
-		<qualifier><![CDATA[artistName like $name]]></qualifier>
-	</query>
-	<query name="ProcedureQuery" type="ProcedureQuery" root="procedure" root-name="cayenne_tst_select_proc" result-entity="Artist">
-	</query>
-	<query name="QueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
-	</query>
-	<query name="QueryWithOrdering" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<ordering descending="true" ignore-case="true"><![CDATA[artistName]]></ordering>
-		<ordering><![CDATA[dateOfBirth]]></ordering>
-	</query>
-	<query name="QueryWithPrefetch" type="SelectQuery" root="obj-entity" root-name="Gallery">
-		<prefetch>paintingArray</prefetch>
-	</query>
-	<query name="QueryWithQualifier" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<qualifier><![CDATA[artistName = $param1]]></qualifier>
-	</query>
-	<query name="QueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
-	</query>
-	<query name="SelectDateTest" type="SQLTemplate" root="data-map" root-name="testmap">
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<sql><![CDATA[SELECT * FROM DATE_TEST]]></sql>
-	</query>
-	<query name="SelectReturnTypesMap1" type="SQLTemplate" root="data-map" root-name="testmap">
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST1]]></sql>
-	</query>
-	<query name="SelectReturnTypesMap2" type="SQLTemplate" root="data-map" root-name="testmap">
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST2]]></sql>
-	</query>
-	<query name="SelectTestLower" type="SQLTemplate" root="data-map" root-name="testmap">
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="LOWER"/>
-		<sql><![CDATA[select * from ARTIST]]></sql>
-	</query>
-	<query name="SelectTestUpper" type="SQLTemplate" root="data-map" root-name="testmap">
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<sql><![CDATA[select * from ARTIST]]></sql>
-	</query>
-</data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/pom.xml
----------------------------------------------------------------------
diff --git a/itests/pom.xml b/itests/pom.xml
deleted file mode 100644
index eea0029..0000000
--- a/itests/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-	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.   
--->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-      <groupId>org.apache.cayenne</groupId>
-      <artifactId>cayenne-parent</artifactId>
-      <version>4.1.M2-SNAPSHOT</version>
-    </parent>
-
-    <groupId>org.apache.cayenne.itests</groupId>
-    <artifactId>cayenne-itests-parent</artifactId>
-    <name>cayenne-itests-parent: Integration Tests Parent</name>
-    <packaging>pom</packaging>
-    
-    <modules>
-	  <module>cayenne-tools-itest</module>
-    </modules>
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-deploy-plugin</artifactId>
-				<configuration>
-					<skip>true</skip>
-				</configuration>
-			</plugin>
-			<!-- This ensures LICENSE and NOTICE inclusion in all jars -->
-            <plugin>
-                <artifactId>maven-remote-resources-plugin</artifactId>
-                <configuration>
-                	<skip>true</skip>
-                </configuration>
-            </plugin>
-		</plugins>
-	</build>
-</project>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/cayenne-tools-itest/pom.xml
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-tools-itest/pom.xml b/maven-plugins/cayenne-tools-itest/pom.xml
new file mode 100644
index 0000000..f173358
--- /dev/null
+++ b/maven-plugins/cayenne-tools-itest/pom.xml
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+	<!--
+		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.
+	-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>cayenne-maven-plugins-parent</artifactId>
+        <groupId>org.apache.cayenne.plugins</groupId>
+        <version>4.1.M2-SNAPSHOT</version>
+    </parent>
+
+	<description>Integration Tests - Cayenne Tools</description>
+	<artifactId>cayenne-tools-itest</artifactId>
+	<name>cayenne-tools-itest: Tools integration tests</name>
+	<packaging>jar</packaging>
+	
+	<properties>
+		<testResourceDir>${project.build.testSourceDirectory}/../resources</testResourceDir>
+		<generatedClassesDir>${project.build.directory}/generated-tests</generatedClassesDir>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>compile</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.cayenne.build-tools</groupId>
+			<artifactId>cayenne-test-utilities</artifactId>
+			<version>${project.version}</version>
+			<scope>compile</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.cayenne</groupId>
+			<artifactId>cayenne-di</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.cayenne</groupId>
+			<artifactId>cayenne-server</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+	</dependencies>
+
+	<build>
+		<plugins>
+			
+			<plugin>
+				<groupId>org.apache.cayenne.plugins</groupId>
+				<artifactId>cayenne-maven-plugin</artifactId>
+				<version>${project.version}</version>
+				<executions>
+				    <execution>
+				        <id>single-classes-cust-template</id>
+				        <goals>
+                            <goal>cgen</goal>
+                        </goals>
+		                <configuration>
+		                  <map>${testResourceDir}/testmap.map.xml</map>
+		                  <destDir>${generatedClassesDir}/single-classes-cust-template</destDir>
+		                  <makePairs>false</makePairs>
+		                  <usePkgPath>true</usePkgPath>
+		                  <template>${testResourceDir}/org/apache/cayenne/tools/velotemplate.vm</template>
+		                </configuration>
+				    </execution>
+				    <execution>
+                        <id>single-classes1</id>
+                        <goals>
+                            <goal>cgen</goal>
+                        </goals>
+                        <configuration>
+                          <map>${testResourceDir}/testmap.map.xml</map>
+                          <destDir>${generatedClassesDir}/single-classes1</destDir>
+                          <makePairs>false</makePairs>
+                          <usePkgPath>true</usePkgPath>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>single-classes2</id>
+                        <goals>
+                            <goal>cgen</goal>
+                        </goals>
+                        <configuration>
+                          <map>${testResourceDir}/testmap.map.xml</map>
+                          <destDir>${generatedClassesDir}/single-classes2</destDir>
+                          <makePairs>false</makePairs>
+                          <usePkgPath>false</usePkgPath>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>pairs1</id>
+                        <goals>
+                            <goal>cgen</goal>
+                        </goals>
+                        <configuration>
+                          <map>${testResourceDir}/testmap.map.xml</map>
+                          <destDir>${generatedClassesDir}/pairs1</destDir>
+                          <makePairs>true</makePairs>
+                          <usePkgPath>true</usePkgPath>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>pairs2</id>
+                        <goals>
+                            <goal>cgen</goal>
+                        </goals>
+                        <configuration>
+                          <map>${testResourceDir}/testmap.map.xml</map>
+                          <destDir>${generatedClassesDir}/pairs2</destDir>
+                          <makePairs>true</makePairs>
+                          <usePkgPath>false</usePkgPath>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>pairs3</id>
+                        <goals>
+                            <goal>cgen</goal>
+                        </goals>
+                        <configuration>
+                          <map>${testResourceDir}/testmap.map.xml</map>
+                          <destDir>${generatedClassesDir}/pairs3</destDir>
+                          <makePairs>true</makePairs>
+                          <usePkgPath>true</usePkgPath>
+                          <superPkg>org.apache.cayenne.testdo.testmap.superart</superPkg>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>pairs1-client</id>
+                        <goals>
+                            <goal>cgen</goal>
+                        </goals>
+                        <configuration>
+                          <map>${testResourceDir}/testmap-client.map.xml</map>
+                          <destDir>${generatedClassesDir}/pairs1-client</destDir>
+                          <client>true</client>
+                          <makePairs>true</makePairs>
+                          <usePkgPath>true</usePkgPath>
+                          <superPkg>org.apache.cayenne.testdo.testmap.client.superart</superPkg>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>pairs-embeddables3</id>
+                        <goals>
+                            <goal>cgen</goal>
+                        </goals>
+                        <configuration>
+                          <map>${testResourceDir}/embeddable.map.xml</map>
+                          <destDir>${generatedClassesDir}/pairs-embeddables3</destDir>
+                          <makePairs>true</makePairs>
+                          <usePkgPath>true</usePkgPath>
+                          <superPkg>org.apache.cayenne.testdo.embeddable.auto</superPkg>
+                        </configuration>
+                    </execution>
+				</executions>
+            </plugin>
+		</plugins>
+	</build>
+</project>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/cayenne-tools-itest/src/test/java/org/apache/cayenne/tools/CayenneGeneratorIntegrationTest.java
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-tools-itest/src/test/java/org/apache/cayenne/tools/CayenneGeneratorIntegrationTest.java b/maven-plugins/cayenne-tools-itest/src/test/java/org/apache/cayenne/tools/CayenneGeneratorIntegrationTest.java
new file mode 100644
index 0000000..2142389
--- /dev/null
+++ b/maven-plugins/cayenne-tools-itest/src/test/java/org/apache/cayenne/tools/CayenneGeneratorIntegrationTest.java
@@ -0,0 +1,186 @@
+/*****************************************************************
+ *   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.tools;
+
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.regex.Pattern;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class CayenneGeneratorIntegrationTest {
+
+    private File testDir;
+
+    private void startTest(String testName) {
+        testDir = new File("target/generated-tests", testName);
+        assertTrue(testDir.isDirectory());
+    }
+
+    /**
+     * Test single classes with a non-standard template.
+     */
+    @Test
+    public void testSingleClassesCustTemplate() throws Exception {
+        startTest("single-classes-cust-template");
+
+        assertContents("org/apache/cayenne/testdo/testmap/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap",
+                "CayenneDataObject");
+        assertExists("org/apache/cayenne/testdo/testmap/_Artist.java");
+    }
+
+    /** Test single classes generation including full package path. */
+    @Test
+    public void testSingleClasses1() throws Exception {
+        startTest("single-classes1");
+
+        assertContents("org/apache/cayenne/testdo/testmap/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap",
+                "BaseDataObject");
+        assertExists("org/apache/cayenne/testdo/testmap/_Artist.java");
+    }
+
+    /** Test single classes generation ignoring package path. */
+    @Test
+    public void testSingleClasses2() throws Exception {
+        startTest("single-classes2");
+
+        assertContents("Artist.java", "Artist", "org.apache.cayenne.testdo.testmap", "BaseDataObject");
+        assertExists("_Artist.java");
+        assertExists("org/apache/cayenne/testdo/testmap/Artist.java");
+    }
+
+    /** Test pairs generation including full package path. */
+    @Test
+    public void testPairs1() throws Exception {
+        startTest("pairs1");
+
+        assertContents("org/apache/cayenne/testdo/testmap/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap",
+                "_Artist");
+        assertContents("org/apache/cayenne/testdo/testmap/auto/_Artist.java", "_Artist",
+                "org.apache.cayenne.testdo.testmap.auto", "BaseDataObject");
+    }
+
+    /** Test pairs generation in the same directory. */
+    @Test
+    public void testPairs2() throws Exception {
+        startTest("pairs2");
+
+        assertContents("Artist.java", "Artist", "org.apache.cayenne.testdo.testmap", "_Artist");
+        assertContents("_Artist.java", "_Artist", "org.apache.cayenne.testdo.testmap", "BaseDataObject");
+        assertExists("org/apache/cayenne/testdo/testmap/Artist.java");
+    }
+
+    /**
+     * Test pairs generation including full package path with superclass and
+     * subclass in different packages.
+     */
+    @Test
+    public void testPairs3() throws Exception {
+        startTest("pairs3");
+
+        assertContents("org/apache/cayenne/testdo/testmap/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap",
+                "_Artist");
+        assertContents("org/apache/cayenne/testdo/testmap/superart/_Artist.java", "_Artist",
+                "org.apache.cayenne.testdo.testmap.superart", "BaseDataObject");
+    }
+
+    @Test
+    public void testPairs1_client() throws Exception {
+        startTest("pairs1-client");
+
+        assertContents("org/apache/cayenne/testdo/testmap/client/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap.client",
+                "_Artist");
+        assertContents("org/apache/cayenne/testdo/testmap/client/superart/_Artist.java", "_Artist",
+                "org.apache.cayenne.testdo.testmap.client.superart", "PersistentObject");
+    }
+
+    @Test
+    public void testPairsEmbeddable3() throws Exception {
+        startTest("pairs-embeddables3");
+
+        assertContents("org/apache/cayenne/testdo/embeddable/EmbedEntity1.java", "EmbedEntity1",
+                "org.apache.cayenne.testdo.embeddable", "_EmbedEntity1");
+        assertContents("org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity1.java", "_EmbedEntity1",
+                "org.apache.cayenne.testdo.embeddable.auto", "BaseDataObject");
+        assertContents("org/apache/cayenne/testdo/embeddable/Embeddable1.java", "Embeddable1",
+                "org.apache.cayenne.testdo.embeddable", "_Embeddable1");
+        assertContents("org/apache/cayenne/testdo/embeddable/auto/_Embeddable1.java", "_Embeddable1",
+                "org.apache.cayenne.testdo.embeddable.auto", "Object");
+    }
+
+    private String convertPath(String unixPath) {
+        return unixPath.replace('/', File.separatorChar);
+    }
+
+    private void assertContents(String filePath, String className, String packageName, String extendsName)
+            throws Exception {
+        File f = new File(testDir, convertPath(filePath));
+        assertTrue("Not a file: " + f.getAbsolutePath(), f.isFile());
+        assertContents(f, className, packageName, extendsName);
+    }
+
+    private void assertExists(String filePath) {
+        File f = new File(testDir, convertPath(filePath));
+        assertFalse(f.exists());
+    }
+
+    private void assertContents(File f, String className, String packageName, String extendsName) throws Exception {
+        
+        try(BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(f)))) {
+            assertPackage(in, packageName);
+            assertClass(in, className, extendsName);
+        } 
+    }
+
+    private void assertPackage(BufferedReader in, String packageName) throws Exception {
+
+        String s = null;
+        while ((s = in.readLine()) != null) {
+            if (Pattern.matches("^package\\s+([^\\s;]+);", s)) {
+                assertTrue(s.indexOf(packageName) > 0);
+                return;
+            }
+        }
+
+        fail("No package declaration found.");
+    }
+
+    private void assertClass(BufferedReader in, String className, String extendsName) throws Exception {
+
+        Pattern classPattern = Pattern.compile("^public\\s+");
+
+        String s = null;
+        while ((s = in.readLine()) != null) {
+            if (classPattern.matcher(s).find()) {
+                assertTrue(s.indexOf(className) > 0);
+                assertTrue(s.indexOf(extendsName) > 0);
+                assertTrue(s.indexOf(className) < s.indexOf(extendsName));
+                return;
+            }
+        }
+
+        fail("No class declaration found.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/cayenne-tools-itest/src/test/resources/cayenne-client.xml
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-tools-itest/src/test/resources/cayenne-client.xml b/maven-plugins/cayenne-tools-itest/src/test/resources/cayenne-client.xml
new file mode 100644
index 0000000..355ac28
--- /dev/null
+++ b/maven-plugins/cayenne-tools-itest/src/test/resources/cayenne-client.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain xmlns="http://cayenne.apache.org/schema/10/domain"
+	 project-version="10">
+	<map name="testmap-client"/>
+</domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/cayenne-tools-itest/src/test/resources/embeddable.map.xml
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-tools-itest/src/test/resources/embeddable.map.xml b/maven-plugins/cayenne-tools-itest/src/test/resources/embeddable.map.xml
new file mode 100644
index 0000000..10c4db6
--- /dev/null
+++ b/maven-plugins/cayenne-tools-itest/src/test/resources/embeddable.map.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd"
+	 project-version="10">
+	<property name="defaultPackage" value="org.apache.cayenne.testdo.embeddable"/>
+	<embeddable className="org.apache.cayenne.testdo.embeddable.Embeddable1">
+		<embeddable-attribute name="embedded10" type="java.lang.String" db-attribute-name="EMBEDDED10"/>
+		<embeddable-attribute name="embedded20" type="java.lang.String" db-attribute-name="EMBEDDED20"/>
+	</embeddable>
+	<db-entity name="EMBED_ENTITY1">
+		<db-attribute name="EMBEDDED10" type="VARCHAR" length="100"/>
+		<db-attribute name="EMBEDDED20" type="VARCHAR" length="100"/>
+		<db-attribute name="EMBEDDED30" type="VARCHAR" length="100"/>
+		<db-attribute name="EMBEDDED40" type="VARCHAR" length="100"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<obj-entity name="EmbedEntity1" className="org.apache.cayenne.testdo.embeddable.EmbedEntity1" dbEntityName="EMBED_ENTITY1">
+		<embedded-attribute name="embedded1" type="org.apache.cayenne.testdo.embeddable.Embeddable1"/>
+		<embedded-attribute name="embedded2" type="org.apache.cayenne.testdo.embeddable.Embeddable1">
+			<embeddable-attribute-override name="embedded10" db-attribute-path="EMBEDDED30"/>
+			<embeddable-attribute-override name="embedded20" db-attribute-path="EMBEDDED40"/>
+		</embedded-attribute>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+</data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen-dependent.map.xml
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen-dependent.map.xml b/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen-dependent.map.xml
new file mode 100644
index 0000000..b72f320
--- /dev/null
+++ b/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen-dependent.map.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/9/modelMap"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://cayenne.apache.org/schema/9/modelMap http://cayenne.apache.org/schema/9/modelMap.xsd"
+	project-version="1.1">
+	<property name="defaultPackage" value="org.apache.cayenne.testdo.cgen2"/>
+	<db-entity name="MYARTGROUP">
+		<db-attribute name="MY_GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="CUSTOM" type="VARCHAR" isMandatory="true" length="100"/>
+		<db-attribute name="MY_PARENT_GROUP_ID" type="INTEGER"/>
+	</db-entity>
+	<obj-entity name="MyArtGroup" className="org.apache.cayenne.testdo.cgen2.MyArtGroup" dbEntityName="MYARTGROUP">
+		<obj-attribute name="custom" type="java.lang.String" db-attribute-path="CUSTOM"/>
+	</obj-entity>
+	<db-relationship name="toParentArtGroup" source="MYARTGROUP" target="ARTGROUP" toMany="false">
+		<db-attribute-pair source="MY_PARENT_GROUP_ID" target="GROUP_ID"/>
+	</db-relationship>
+	<obj-relationship name="toParentGroup" source="MyArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toParentArtGroup"/>
+</data-map>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen.map.xml
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen.map.xml b/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen.map.xml
new file mode 100644
index 0000000..56a2d92
--- /dev/null
+++ b/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen.map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/9/modelMap"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/9/modelMap http://cayenne.apache.org/schema/9/modelMap.xsd"
+	 project-version="9">
+
+	<db-entity name="ARTGROUP">
+		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" isMandatory="true" length="100"/>
+		<db-attribute name="PARENT_GROUP_ID" type="INTEGER"/>
+	</db-entity>
+	<obj-entity name="ArtGroup" className="org.apache.cayenne.testdo.testmap.ArtGroup" dbEntityName="ARTGROUP">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+</data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/velotemplate.vm
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/velotemplate.vm b/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/velotemplate.vm
new file mode 100644
index 0000000..1ca078c
--- /dev/null
+++ b/maven-plugins/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/velotemplate.vm
@@ -0,0 +1,13 @@
+## Test Velocity template
+${importUtils.setPackage($subPackageName)}##
+${importUtils.generate()}
+
+import java.util.List;
+import org.apache.cayenne.*;
+
+/** Class ${classGen.superPrefix}${classGen.className} was generated by Cayenne.
+  * It is probably a good idea to avoid changing this class manually, 
+  * since it may be overwritten next time code is regenerated. 
+  * If you need to make any customizations, please use subclass. 
+  */
+public class ${subClassName} extends CayenneDataObject {


[3/9] cayenne git commit: CAY-2403

Posted by nt...@apache.org.
CAY-2403


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

Branch: refs/heads/master
Commit: ab1fd0bf471954b94aba1aeda0c149175de50929
Parents: 023547e
Author: Arseni Bulatski <an...@gmail.com>
Authored: Fri Feb 2 15:24:03 2018 +0300
Committer: Arseni Bulatski <an...@gmail.com>
Committed: Fri Feb 2 15:24:03 2018 +0300

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |   1 +
 cayenne-jgroups/pom.xml                         |  82 +++++
 .../org/apache/cayenne/event/JGroupsModule.java |  63 ++++
 .../event/JGroupsServerModuleProvider.java      |  50 +++
 .../apache/cayenne/event/JavaGroupsBridge.java  | 231 ++++++++++++++
 .../cayenne/event/JavaGroupsBridgeFactory.java  |  49 +++
 .../cayenne/event/JavaGroupsBridgeProvider.java |  50 +++
 ...iguration.server.CayenneServerModuleProvider |  20 ++
 .../event/CayenneJGroupsModuleProviderTest.java |  36 +++
 .../event/JavaGroupsBridgeFactoryTest.java      |  84 +++++
 .../event/JavaGroupsBridgeProviderTest.java     |  97 ++++++
 cayenne-jms/pom.xml                             |  81 +++++
 .../org/apache/cayenne/event/JMSBridge.java     | 280 +++++++++++++++++
 .../apache/cayenne/event/JMSBridgeFactory.java  |  39 +++
 .../apache/cayenne/event/JMSBridgeProvider.java |  50 +++
 .../org/apache/cayenne/event/JMSModule.java     |  54 ++++
 .../cayenne/event/JMSServerModuleProvider.java  |  50 +++
 ...iguration.server.CayenneServerModuleProvider |  20 ++
 .../event/CayenneJMSModuleProviderTest.java     |  36 +++
 .../cayenne/event/JMSBridgeFactoryTest.java     |  77 +++++
 .../cayenne/event/JMSBridgeProviderTest.java    |  87 ++++++
 cayenne-xmpp/pom.xml                            |  86 ++++++
 .../org/apache/cayenne/event/XMPPBridge.java    | 308 +++++++++++++++++++
 .../apache/cayenne/event/XMPPBridgeFactory.java |  41 +++
 .../cayenne/event/XMPPBridgeProvider.java       |  50 +++
 .../org/apache/cayenne/event/XMPPModule.java    |  71 +++++
 .../cayenne/event/XMPPServerModuleProvider.java |  50 +++
 ...iguration.server.CayenneServerModuleProvider |  20 ++
 .../event/CayenneXMPPModuleProviderTest.java    |  36 +++
 .../cayenne/event/XMPPBridgeFactoryTest.java    |  72 +++++
 .../cayenne/event/XMPPBridgeProviderTest.java   | 105 +++++++
 .../apache/cayenne/event/XMPPBridgeTest.java    |  54 ++++
 eventbridges/cayenne-jgroups/pom.xml            |  41 ---
 .../org/apache/cayenne/event/JGroupsModule.java |  63 ----
 .../event/JGroupsServerModuleProvider.java      |  50 ---
 .../apache/cayenne/event/JavaGroupsBridge.java  | 231 --------------
 .../cayenne/event/JavaGroupsBridgeFactory.java  |  49 ---
 .../cayenne/event/JavaGroupsBridgeProvider.java |  50 ---
 ...iguration.server.CayenneServerModuleProvider |  20 --
 .../event/CayenneJGroupsModuleProviderTest.java |  36 ---
 .../event/JavaGroupsBridgeFactoryTest.java      |  84 -----
 .../event/JavaGroupsBridgeProviderTest.java     |  97 ------
 eventbridges/cayenne-jms/pom.xml                |  41 ---
 .../org/apache/cayenne/event/JMSBridge.java     | 280 -----------------
 .../apache/cayenne/event/JMSBridgeFactory.java  |  39 ---
 .../apache/cayenne/event/JMSBridgeProvider.java |  50 ---
 .../org/apache/cayenne/event/JMSModule.java     |  54 ----
 .../cayenne/event/JMSServerModuleProvider.java  |  50 ---
 ...iguration.server.CayenneServerModuleProvider |  20 --
 .../event/CayenneJMSModuleProviderTest.java     |  36 ---
 .../cayenne/event/JMSBridgeFactoryTest.java     |  77 -----
 .../cayenne/event/JMSBridgeProviderTest.java    |  87 ------
 eventbridges/cayenne-xmpp/pom.xml               |  46 ---
 .../org/apache/cayenne/event/XMPPBridge.java    | 308 -------------------
 .../apache/cayenne/event/XMPPBridgeFactory.java |  41 ---
 .../cayenne/event/XMPPBridgeProvider.java       |  50 ---
 .../org/apache/cayenne/event/XMPPModule.java    |  71 -----
 .../cayenne/event/XMPPServerModuleProvider.java |  50 ---
 ...iguration.server.CayenneServerModuleProvider |  20 --
 .../event/CayenneXMPPModuleProviderTest.java    |  36 ---
 .../cayenne/event/XMPPBridgeFactoryTest.java    |  72 -----
 .../cayenne/event/XMPPBridgeProviderTest.java   | 105 -------
 .../apache/cayenne/event/XMPPBridgeTest.java    |  54 ----
 eventbridges/pom.xml                            |  82 -----
 pom.xml                                         |   4 +-
 65 files changed, 2433 insertions(+), 2391 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 746012c..dbf604a 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -21,6 +21,7 @@ CAY-2393 Add sqlserver-docker profile to automate tests on SQLServer
 CAY-2394 Upgrade to Apache Velocity 2.0
 CAY-2395 cdbimport: add option to create project file
 CAY-2396 Upgrade maven-assembly-plugin to 3.1.0
+CAY-2403 Extract eventbridges to top level
 
 Bug Fixes:
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jgroups/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/pom.xml b/cayenne-jgroups/pom.xml
new file mode 100644
index 0000000..9698a38
--- /dev/null
+++ b/cayenne-jgroups/pom.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>cayenne-parent</artifactId>
+        <groupId>org.apache.cayenne</groupId>
+        <version>4.1.M2-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>cayenne-jgroups</artifactId>
+    <name>cayenne-jgroups: Cayenne JGroups Event bridge</name>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>jgroups</groupId>
+            <artifactId>jgroups-all</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-server</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- This ensures LICENSE and NOTICE inclusion in all jars -->
+            <plugin>
+                <artifactId>maven-remote-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>process</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java b/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java
new file mode 100644
index 0000000..77738c3
--- /dev/null
+++ b/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java
@@ -0,0 +1,63 @@
+/*****************************************************************
+ *   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.Binder;
+import org.apache.cayenne.di.MapBuilder;
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.0
+ */
+public class JGroupsModule implements Module {
+
+    /**
+     * 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";
+
+    public static void contributeMulticastAddress(Binder binder, String address) {
+        contributeProperties(binder).put(JavaGroupsBridge.MCAST_ADDRESS_PROPERTY, address);
+    }
+
+    public static void contributeMulticastPort(Binder binder, int port) {
+        contributeProperties(binder).put(JavaGroupsBridge.MCAST_PORT_PROPERTY, Integer.toString(port));
+    }
+
+    public static void contributeConfigUrl(Binder binder, String config) {
+        contributeProperties(binder).put(JavaGroupsBridge.JGROUPS_CONFIG_URL_PROPERTY, config);
+    }
+
+    private static MapBuilder<String> contributeProperties(Binder binder) {
+        return binder.bindMap(String.class, JAVA_GROUPS_BRIDGE_PROPERTIES_MAP);
+    }
+
+    @Override
+    public void configure(Binder binder) {
+        // init properties' defaults
+        contributeMulticastAddress(binder, JavaGroupsBridge.MCAST_ADDRESS_DEFAULT);
+        contributeMulticastPort(binder, JavaGroupsBridge.MCAST_PORT_DEFAULT_INT);
+
+        binder.bind(EventBridge.class).toProvider(JavaGroupsBridgeProvider.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java b/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java
new file mode 100644
index 0000000..60c5bcd
--- /dev/null
+++ b/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.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 java.util.Collection;
+import java.util.Collections;
+
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.configuration.server.ServerModule;
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.0
+ */
+public class JGroupsServerModuleProvider implements CayenneServerModuleProvider {
+
+    @Override
+    public Module module() {
+        return new JGroupsModule();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return JGroupsModule.class;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Collection<Class<? extends Module>> overrides() {
+        Collection modules = Collections.singletonList(ServerModule.class);
+        return modules;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java b/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
new file mode 100644
index 0000000..cd7bae2
--- /dev/null
+++ b/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java
@@ -0,0 +1,231 @@
+/*****************************************************************
+ *   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.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.
+ * 
+ * @since 1.1
+ */
+public class JavaGroupsBridge extends EventBridge implements MessageListener {
+
+    public static final String MCAST_ADDRESS_DEFAULT = "228.0.0.5";
+    public static final int MCAST_PORT_DEFAULT_INT = 22222;
+    public static final String MCAST_PORT_DEFAULT = Integer.toString(MCAST_PORT_DEFAULT_INT);
+
+    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;
+
+    protected Channel channel;
+    protected PullPushAdapter adapter;
+    protected String multicastAddress;
+    protected String multicastPort;
+    protected String configURL;
+
+    /**
+     * Creates new instance of JavaGroupsBridge.
+     */
+    public JavaGroupsBridge(EventSubject localSubject, String externalSubject) {
+        super(localSubject, externalSubject);
+    }
+
+    /**
+     * @since 1.2
+     */
+    public JavaGroupsBridge(Collection<EventSubject> localSubjects, String externalSubject) {
+        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;
+    }
+
+    public void setConfigURL(String configURL) {
+        this.configURL = configURL;
+    }
+
+    public String getMulticastAddress() {
+        return multicastAddress;
+    }
+
+    public void setMulticastAddress(String multicastAddress) {
+        this.multicastAddress = multicastAddress;
+    }
+
+    public String getMulticastPort() {
+        return multicastPort;
+    }
+
+    public void setMulticastPort(String multicastPort) {
+        this.multicastPort = multicastPort;
+    }
+
+    public byte[] getState() {
+        return state;
+    }
+
+    public void setState(byte[] state) {
+        this.state = state;
+    }
+
+    /**
+     * Implementation of org.javagroups.MessageListener - a callback method to process
+     * incoming messages.
+     */
+    public void receive(Message message) {
+        try {
+            CayenneEvent event = messageObjectToEvent((Serializable) message.getObject());
+            if (event != null) {
+
+                onExternalEvent(event);
+            }
+        }
+        catch (Exception ex) {
+            // TODO: Andrus, 2/8/2006 logging... Log4J was removed to make this usable on
+            // the client
+        }
+    }
+
+    @Override
+    protected void startupExternal() throws Exception {
+        // TODO: need to do more research to figure out the best default transport
+        // settings
+        // to avoid fragmentation, etc.
+
+        // if config file is set, use it, otherwise use a default
+        // set of properties, trying to configure multicast address and port
+        if (configURL != null) {
+            channel = new JChannel(configURL);
+        }
+        else {
+            String configString = buildConfigString();
+            channel = new JChannel(configString);
+        }
+
+        // Important - discard messages from self
+        channel.setOpt(Channel.LOCAL, Boolean.FALSE);
+        channel.connect(externalSubject);
+
+        if (receivesExternalEvents()) {
+            adapter = new PullPushAdapter(channel, this);
+        }
+    }
+
+    /**
+     * Creates JavaGroups configuration String, using preconfigured multicast port and
+     * address.
+     */
+    protected String buildConfigString() {
+        if (multicastAddress == null) {
+            throw new IllegalStateException("'multcastAddress' is not set");
+        }
+
+        if (multicastPort == null) {
+            throw new IllegalStateException("'multcastPort' is not set");
+        }
+
+        return "UDP(mcast_addr="
+                + multicastAddress
+                + ";mcast_port="
+                + multicastPort
+                + ";ip_ttl=32):"
+                + "PING(timeout=3000;num_initial_members=6):"
+                + "FD(timeout=3000):"
+                + "VERIFY_SUSPECT(timeout=1500):"
+                + "pbcast.NAKACK(gc_lag=10;retransmit_timeout=600,1200,2400,4800):"
+                + "pbcast.STABLE(desired_avg_gossip=10000):"
+                + "FRAG:"
+                + "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;"
+                + "shun=true;print_local_addr=false)";
+    }
+
+    @Override
+    protected void shutdownExternal() throws Exception {
+        try {
+            if (adapter != null) {
+                adapter.stop();
+            }
+
+            channel.close();
+        }
+        finally {
+            adapter = null;
+            channel = null;
+        }
+    }
+
+    @Override
+    protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
+        Message message = new Message(null, null, eventToMessageObject(localEvent));
+        channel.send(message);
+    }
+
+    /**
+     * Converts CayenneEvent to a serializable object that will be sent via JMS. Default
+     * implementation simply returns the event, but subclasses can customize this
+     * behavior.
+     */
+    protected Serializable eventToMessageObject(CayenneEvent event) throws Exception {
+        return event;
+    }
+
+    /**
+     * Converts a Serializable instance to CayenneEvent. Returns null if the object is not
+     * supported. Default implementation simply tries to cast the object to CayenneEvent,
+     * but subclasses can customize this behavior.
+     */
+    protected CayenneEvent messageObjectToEvent(Serializable object) throws Exception {
+        return (object instanceof CayenneEvent) ? (CayenneEvent) object : null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java b/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
new file mode 100644
index 0000000..302e5ca
--- /dev/null
+++ b/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java
@@ -0,0 +1,49 @@
+/*****************************************************************
+ *   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 java.util.Collection;
+import java.util.Map;
+
+/**
+ * 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 {
+
+    /**
+     * Creates a JavaGroupsBridge instance. Since JavaGroups is not shipped with Cayenne
+     * and should be installed separately, a common misconfiguration problem may be the
+     * absence of JavaGroups jar file. This factory returns a dummy noop EventBridge, if
+     * this is the case. This would allow the application to continue to run, but without
+     * remote notifications.
+     */
+    public EventBridge createEventBridge(
+            Collection<EventSubject> localSubjects,
+            String externalSubject,
+            Map<String, String> properties) {
+        return new JavaGroupsBridge(localSubjects, externalSubject, properties);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java b/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java
new file mode 100644
index 0000000..983aa7f
--- /dev/null
+++ b/cayenne-jgroups/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(JGroupsModule.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/ab1fd0bf/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
new file mode 100644
index 0000000..b6c6632
--- /dev/null
+++ b/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+#   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.
+##################################################################
+
+org.apache.cayenne.event.JGroupsServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java b/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java
new file mode 100644
index 0000000..320d490
--- /dev/null
+++ b/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java
@@ -0,0 +1,36 @@
+/*****************************************************************
+ *   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.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.unit.util.ModuleProviderChecker;
+import org.junit.Test;
+
+/**
+ * @since 4.0
+ */
+public class CayenneJGroupsModuleProviderTest {
+
+    @Test
+    public void testAutoLoadable() {
+        ModuleProviderChecker.testProviderPresent(JGroupsServerModuleProvider.class, CayenneServerModuleProvider.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java b/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java
new file mode 100644
index 0000000..694dc24
--- /dev/null
+++ b/cayenne-jgroups/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.<String, String>emptyMap());
+
+        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<>();
+        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.<String, String>emptyMap());
+
+        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/ab1fd0bf/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java b/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java
new file mode 100644
index 0000000..00232d4
--- /dev/null
+++ b/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java
@@ -0,0 +1,97 @@
+/*****************************************************************
+ *   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.Slf4jJdbcEventLogger;
+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 {
+        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JGroupsModule());
+        EventBridge bridge = injector.getInstance(EventBridge.class);
+
+        assertNotNull(bridge);
+        assertTrue(bridge instanceof JavaGroupsBridge);
+    }
+
+    @Test
+    public void testUseProperties() throws Exception {
+        Module module = binder -> {
+            JGroupsModule.contributeMulticastAddress(binder, MCAST_ADDRESS_TEST);
+            JGroupsModule.contributeMulticastPort(binder, Integer.parseInt(MCAST_PORT_TEST));
+            JGroupsModule.contributeConfigUrl(binder, CONFIG_URL_TEST);
+        };
+
+        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JGroupsModule(), 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 {
+        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JGroupsModule());
+        JavaGroupsBridge bridge = (JavaGroupsBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(JavaGroupsBridge.MCAST_ADDRESS_DEFAULT, bridge.getMulticastAddress());
+        assertEquals(JavaGroupsBridge.MCAST_PORT_DEFAULT, bridge.getMulticastPort());
+        assertEquals(null, bridge.getConfigURL());
+    }
+
+    class DefaultBindings implements Module {
+        @Override
+        public void configure(Binder binder) {
+            binder.bindMap(String.class, 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(Slf4jJdbcEventLogger.class);
+            binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jms/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-jms/pom.xml b/cayenne-jms/pom.xml
new file mode 100644
index 0000000..f4da57b
--- /dev/null
+++ b/cayenne-jms/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>cayenne-parent</artifactId>
+        <groupId>org.apache.cayenne</groupId>
+        <version>4.1.M2-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>cayenne-jms</artifactId>
+    <name>cayenne-jms: Cayenne JMS Event bridge</name>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jms_1.1_spec</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-server</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- This ensures LICENSE and NOTICE inclusion in all jars -->
+            <plugin>
+                <artifactId>maven-remote-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>process</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java
----------------------------------------------------------------------
diff --git a/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java b/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java
new file mode 100644
index 0000000..0b746fc
--- /dev/null
+++ b/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java
@@ -0,0 +1,280 @@
+/*****************************************************************
+ *   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.util.IDUtil;
+
+import javax.jms.Message;
+import javax.jms.MessageFormatException;
+import javax.jms.MessageListener;
+import javax.jms.ObjectMessage;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.jms.TopicConnectionFactory;
+import javax.jms.TopicPublisher;
+import javax.jms.TopicSession;
+import javax.jms.TopicSubscriber;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Implementation of EventBridge that passes and receives events via JMS (Java Messaging
+ * Service). JMSBridge uses "publish/subscribe" model for communication with external
+ * agents.
+ * 
+ * @since 1.1
+ */
+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_PROPERTY = "VM_ID";
+
+    protected String topicConnectionFactoryName;
+
+    protected TopicConnection sendConnection;
+    protected TopicSession sendSession;
+    protected TopicConnection receivedConnection;
+    protected TopicPublisher publisher;
+    protected TopicSubscriber subscriber;
+
+    public JMSBridge(EventSubject localSubject, String externalSubject) {
+        super(localSubject, externalSubject);
+    }
+
+    /**
+     * @since 1.2
+     */
+    public JMSBridge(Collection<EventSubject> localSubjects, String externalSubject) {
+        super(localSubjects, externalSubject);
+    }
+
+    /**
+     * @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_PROPERTY);
+            if (JMSBridge.VM_ID.equals(vmID)) {
+                return;
+            }
+
+            if (!(message instanceof ObjectMessage)) {
+                return;
+            }
+
+            ObjectMessage objectMessage = (ObjectMessage) message;
+            CayenneEvent event = messageObjectToEvent(objectMessage.getObject());
+            if (event != null) {
+                onExternalEvent(event);
+            }
+
+        }
+        catch (MessageFormatException mfex) {
+            // TODO: Andrus, 2/8/2006 logging... Log4J was removed to make this usable on
+            // the client
+        }
+        catch (Exception ex) {
+            // TODO: Andrus, 2/8/2006 logging... Log4J was removed to make this usable on
+            // the client
+        }
+    }
+
+    /**
+     * @return Name of javax.jms.TopicConnectionFactory accessible via JNDI.
+     */
+    public String getTopicConnectionFactoryName() {
+        return topicConnectionFactoryName;
+    }
+
+    public void setTopicConnectionFactoryName(String name) {
+        this.topicConnectionFactoryName = name;
+    }
+
+    /**
+     * Starts up JMS machinery for "publish/subscribe" model.
+     */
+    @Override
+    protected void startupExternal() throws Exception {
+        Context jndiContext = new InitialContext();
+        TopicConnectionFactory connectionFactory = (TopicConnectionFactory) jndiContext
+                .lookup(topicConnectionFactoryName);
+
+        Topic topic = null;
+
+        try {
+            topic = (Topic) jndiContext.lookup(externalSubject);
+        }
+        catch (NameNotFoundException ex) {
+            // can't find topic, try to create it
+            topic = topicNotFound(jndiContext, ex);
+
+            if (topic == null) {
+                throw ex;
+            }
+        }
+
+        // config publisher
+        if (receivesLocalEvents()) {
+            this.sendConnection = connectionFactory.createTopicConnection();
+            this.sendSession = sendConnection.createTopicSession(
+                    false,
+                    Session.AUTO_ACKNOWLEDGE);
+            this.publisher = sendSession.createPublisher(topic);
+        }
+
+        // config subscriber
+        if (receivesExternalEvents()) {
+            this.receivedConnection = connectionFactory.createTopicConnection();
+            this.subscriber = receivedConnection.createTopicSession(
+                    false,
+                    Session.AUTO_ACKNOWLEDGE).createSubscriber(topic);
+            this.subscriber.setMessageListener(this);
+            this.receivedConnection.start();
+        }
+    }
+
+    /**
+     * Attempts to create missing Topic. Since Topic creation is JMS-implementation
+     * specific, this task is left to subclasses. Current implementation simply rethrows
+     * the exception.
+     */
+    protected Topic topicNotFound(Context jndiContext, NamingException ex)
+            throws Exception {
+        throw ex;
+    }
+
+    /**
+     * Closes all resources used to communicate via JMS.
+     */
+    @Override
+    protected void shutdownExternal() throws Exception {
+        Exception lastException = null;
+
+        if (publisher != null) {
+            try {
+                publisher.close();
+            }
+            catch (Exception ex) {
+                lastException = ex;
+            }
+        }
+
+        if (subscriber != null) {
+            try {
+                subscriber.close();
+            }
+            catch (Exception ex) {
+                lastException = ex;
+            }
+        }
+
+        if (receivedConnection != null) {
+            try {
+                receivedConnection.close();
+            }
+            catch (Exception ex) {
+                lastException = ex;
+            }
+        }
+
+        if (sendSession != null) {
+            try {
+                sendSession.close();
+            }
+            catch (Exception ex) {
+                lastException = ex;
+            }
+        }
+
+        if (sendConnection != null) {
+            try {
+                sendConnection.close();
+            }
+            catch (Exception ex) {
+                lastException = ex;
+            }
+        }
+
+        publisher = null;
+        subscriber = null;
+        receivedConnection = null;
+        sendConnection = null;
+        sendSession = null;
+
+        if (lastException != null) {
+            throw lastException;
+        }
+    }
+
+    @Override
+    protected void sendExternalEvent(CayenneEvent localEvent) throws Exception {
+        ObjectMessage message = sendSession
+                .createObjectMessage(eventToMessageObject(localEvent));
+        message.setObjectProperty(JMSBridge.VM_ID_PROPERTY, JMSBridge.VM_ID);
+        publisher.publish(message);
+    }
+
+    /**
+     * Converts CayenneEvent to a serializable object that will be sent via JMS. Default
+     * implementation simply returns the event, but subclasses can customize this
+     * behavior.
+     */
+    protected Serializable eventToMessageObject(CayenneEvent event) throws Exception {
+        return event;
+    }
+
+    /**
+     * Converts a Serializable instance to CayenneEvent. Returns null if the object is not
+     * supported. Default implementation simply tries to cast the object to CayenneEvent,
+     * but subclasses can customize this behavior.
+     */
+    protected CayenneEvent messageObjectToEvent(Serializable object) throws Exception {
+        return (object instanceof CayenneEvent) ? (CayenneEvent) object : null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java b/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
new file mode 100644
index 0000000..b7772d8
--- /dev/null
+++ b/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java
@@ -0,0 +1,39 @@
+/*****************************************************************
+ *   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 java.util.Collection;
+import java.util.Map;
+
+/**
+ * Factory to create JMSBridge instances.
+ * 
+ * @since 1.1
+ */
+public class JMSBridgeFactory implements EventBridgeFactory {
+
+    /**
+     * @since 1.2
+     */
+    public EventBridge createEventBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) {
+        return new JMSBridge(localSubjects, externalSubject, properties);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java b/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java
new file mode 100644
index 0000000..6a06faa
--- /dev/null
+++ b/cayenne-jms/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(JMSModule.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/ab1fd0bf/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSModule.java
----------------------------------------------------------------------
diff --git a/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSModule.java b/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSModule.java
new file mode 100644
index 0000000..b532bc5
--- /dev/null
+++ b/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSModule.java
@@ -0,0 +1,54 @@
+/*****************************************************************
+ *   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.Binder;
+import org.apache.cayenne.di.MapBuilder;
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.0
+ */
+public class JMSModule implements Module {
+
+    /**
+     * 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";
+
+    public static void contributeTopicConnectionFactory(Binder binder, String factory) {
+        contributeProperties(binder).put(JMSBridge.TOPIC_CONNECTION_FACTORY_PROPERTY, factory);
+    }
+
+    private static MapBuilder<String> contributeProperties(Binder binder) {
+        return binder.bindMap(String.class, JMS_BRIDGE_PROPERTIES_MAP);
+    }
+
+    @Override
+    public void configure(Binder binder) {
+        // init properties' defaults
+        contributeTopicConnectionFactory(binder, JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT);
+
+        binder.bind(EventBridge.class).toProvider(JMSBridgeProvider.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSServerModuleProvider.java b/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSServerModuleProvider.java
new file mode 100644
index 0000000..6979d21
--- /dev/null
+++ b/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSServerModuleProvider.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 java.util.Collection;
+import java.util.Collections;
+
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.configuration.server.ServerModule;
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.0
+ */
+public class JMSServerModuleProvider implements CayenneServerModuleProvider {
+
+    @Override
+    public Module module() {
+        return new JMSModule();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return JMSModule.class;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Collection<Class<? extends Module>> overrides() {
+        Collection modules = Collections.singletonList(ServerModule.class);
+        return modules;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jms/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-jms/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/cayenne-jms/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
new file mode 100644
index 0000000..7c54e3f
--- /dev/null
+++ b/cayenne-jms/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+#   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.
+##################################################################
+
+org.apache.cayenne.event.JMSServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jms/src/test/java/org/apache/cayenne/event/CayenneJMSModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-jms/src/test/java/org/apache/cayenne/event/CayenneJMSModuleProviderTest.java b/cayenne-jms/src/test/java/org/apache/cayenne/event/CayenneJMSModuleProviderTest.java
new file mode 100644
index 0000000..3b3e87a
--- /dev/null
+++ b/cayenne-jms/src/test/java/org/apache/cayenne/event/CayenneJMSModuleProviderTest.java
@@ -0,0 +1,36 @@
+/*****************************************************************
+ *   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.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.unit.util.ModuleProviderChecker;
+import org.junit.Test;
+
+/**
+ * @since 4.0
+ */
+public class CayenneJMSModuleProviderTest {
+
+    @Test
+    public void testAutoLoadable() {
+        ModuleProviderChecker.testProviderPresent(JMSServerModuleProvider.class, CayenneServerModuleProvider.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java b/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java
new file mode 100644
index 0000000..1e50145
--- /dev/null
+++ b/cayenne-jms/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.<String, String>emptyMap());
+
+        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<>();
+        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.<String, String>emptyMap());
+
+        assertEquals(bridge.getTopicConnectionFactoryName(), JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java b/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java
new file mode 100644
index 0000000..83404eb
--- /dev/null
+++ b/cayenne-jms/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java
@@ -0,0 +1,87 @@
+/*****************************************************************
+ *   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.Slf4jJdbcEventLogger;
+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 {
+        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JMSModule());
+        EventBridge bridge = injector.getInstance(EventBridge.class);
+
+        assertNotNull(bridge);
+        assertTrue(bridge instanceof JMSBridge);
+    }
+
+    @Test
+    public void testUseProperties() {
+        Module module = binder -> JMSModule.contributeTopicConnectionFactory(binder, TOPIC_CONNECTION_FACTORY_TEST);
+
+        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JMSModule(), module);
+        JMSBridge bridge = (JMSBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(TOPIC_CONNECTION_FACTORY_TEST, bridge.getTopicConnectionFactoryName());
+    }
+
+    @Test
+    public void testUseDefaultProperties() throws Exception {
+        Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JMSModule());
+        JMSBridge bridge = (JMSBridge) injector.getInstance(EventBridge.class);
+
+        assertEquals(JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT, bridge.getTopicConnectionFactoryName());
+    }
+
+    class DefaultBindings implements Module {
+        @Override
+        public void configure(Binder binder) {
+            binder.bindMap(String.class, 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(Slf4jJdbcEventLogger.class);
+            binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-xmpp/pom.xml b/cayenne-xmpp/pom.xml
new file mode 100644
index 0000000..cf3f849
--- /dev/null
+++ b/cayenne-xmpp/pom.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>cayenne-parent</artifactId>
+        <groupId>org.apache.cayenne</groupId>
+        <version>4.1.M2-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>cayenne-xmpp</artifactId>
+    <name>cayenne-xmpp: Cayenne XMPP Event bridge</name>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>jivesoftware</groupId>
+            <artifactId>smack</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>jivesoftware</groupId>
+            <artifactId>smackx</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-server</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- This ensures LICENSE and NOTICE inclusion in all jars -->
+            <plugin>
+                <artifactId>maven-remote-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>process</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file


[8/9] cayenne git commit: CAY-2404

Posted by nt...@apache.org.
CAY-2404


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

Branch: refs/heads/master
Commit: 6378c41f7ced5961c892e132110a357872f3fb58
Parents: 023547e
Author: Arseni Bulatski <an...@gmail.com>
Authored: Fri Feb 2 15:55:39 2018 +0300
Committer: Arseni Bulatski <an...@gmail.com>
Committed: Mon Feb 5 10:01:44 2018 +0300

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |   1 +
 itests/cayenne-tools-itest/pom.xml              | 178 -----
 .../tools/CayenneGeneratorIntegrationTest.java  | 186 -----
 .../src/test/resources/cayenne-client.xml       |   5 -
 .../src/test/resources/embeddable.map.xml       |  27 -
 .../apache/cayenne/tools/cgen-dependent.map.xml |  19 -
 .../org/apache/cayenne/tools/cgen.map.xml       |  15 -
 .../org/apache/cayenne/tools/velotemplate.vm    |  13 -
 .../src/test/resources/testmap-client.map.xml   | 730 ------------------
 .../src/test/resources/testmap.map.xml          | 735 -------------------
 itests/pom.xml                                  |  57 --
 maven-plugins/cayenne-tools-itest/pom.xml       | 178 +++++
 .../tools/CayenneGeneratorIntegrationTest.java  | 186 +++++
 .../src/test/resources/cayenne-client.xml       |   5 +
 .../src/test/resources/embeddable.map.xml       |  27 +
 .../apache/cayenne/tools/cgen-dependent.map.xml |  19 +
 .../org/apache/cayenne/tools/cgen.map.xml       |  15 +
 .../org/apache/cayenne/tools/velotemplate.vm    |  13 +
 .../src/test/resources/testmap-client.map.xml   | 730 ++++++++++++++++++
 .../src/test/resources/testmap.map.xml          | 735 +++++++++++++++++++
 maven-plugins/pom.xml                           |   8 +
 pom.xml                                         |   1 -
 22 files changed, 1917 insertions(+), 1966 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 746012c..6ec11fb 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -21,6 +21,7 @@ CAY-2393 Add sqlserver-docker profile to automate tests on SQLServer
 CAY-2394 Upgrade to Apache Velocity 2.0
 CAY-2395 cdbimport: add option to create project file
 CAY-2396 Upgrade maven-assembly-plugin to 3.1.0
+CAY-2404 Move itests to maven-plugins
 
 Bug Fixes:
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/cayenne-tools-itest/pom.xml
----------------------------------------------------------------------
diff --git a/itests/cayenne-tools-itest/pom.xml b/itests/cayenne-tools-itest/pom.xml
deleted file mode 100644
index 89607a8..0000000
--- a/itests/cayenne-tools-itest/pom.xml
+++ /dev/null
@@ -1,178 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-	<!--
-		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.
-	-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-	<modelVersion>4.0.0</modelVersion>
-
-	<parent>
-		<groupId>org.apache.cayenne.itests</groupId>
-		<artifactId>cayenne-itests-parent</artifactId>
-		<version>4.1.M2-SNAPSHOT</version>
-	</parent>
-
-	<description>Integration Tests - Cayenne Tools</description>
-	<artifactId>cayenne-tools-itest</artifactId>
-	<name>cayenne-tools-itest: Tools integration tests</name>
-	<packaging>jar</packaging>
-	
-	<properties>
-		<testResourceDir>${project.build.testSourceDirectory}/../resources</testResourceDir>
-		<generatedClassesDir>${project.build.directory}/generated-tests</generatedClassesDir>
-	</properties>
-
-	<dependencies>
-		<dependency>
-			<groupId>junit</groupId>
-			<artifactId>junit</artifactId>
-			<scope>compile</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>org.apache.cayenne.build-tools</groupId>
-			<artifactId>cayenne-test-utilities</artifactId>
-			<version>${project.version}</version>
-			<scope>compile</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>org.apache.cayenne</groupId>
-			<artifactId>cayenne-di</artifactId>
-			<version>${project.version}</version>
-		</dependency>
-
-		<dependency>
-			<groupId>org.apache.cayenne</groupId>
-			<artifactId>cayenne-server</artifactId>
-			<version>${project.version}</version>
-		</dependency>
-
-	</dependencies>
-
-	<build>
-		<plugins>
-			
-			<plugin>
-				<groupId>org.apache.cayenne.plugins</groupId>
-				<artifactId>cayenne-maven-plugin</artifactId>
-				<version>${project.version}</version>
-				<executions>
-				    <execution>
-				        <id>single-classes-cust-template</id>
-				        <goals>
-                            <goal>cgen</goal>
-                        </goals>
-		                <configuration>
-		                  <map>${testResourceDir}/testmap.map.xml</map>
-		                  <destDir>${generatedClassesDir}/single-classes-cust-template</destDir>
-		                  <makePairs>false</makePairs>
-		                  <usePkgPath>true</usePkgPath>
-		                  <template>${testResourceDir}/org/apache/cayenne/tools/velotemplate.vm</template>
-		                </configuration>
-				    </execution>
-				    <execution>
-                        <id>single-classes1</id>
-                        <goals>
-                            <goal>cgen</goal>
-                        </goals>
-                        <configuration>
-                          <map>${testResourceDir}/testmap.map.xml</map>
-                          <destDir>${generatedClassesDir}/single-classes1</destDir>
-                          <makePairs>false</makePairs>
-                          <usePkgPath>true</usePkgPath>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>single-classes2</id>
-                        <goals>
-                            <goal>cgen</goal>
-                        </goals>
-                        <configuration>
-                          <map>${testResourceDir}/testmap.map.xml</map>
-                          <destDir>${generatedClassesDir}/single-classes2</destDir>
-                          <makePairs>false</makePairs>
-                          <usePkgPath>false</usePkgPath>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>pairs1</id>
-                        <goals>
-                            <goal>cgen</goal>
-                        </goals>
-                        <configuration>
-                          <map>${testResourceDir}/testmap.map.xml</map>
-                          <destDir>${generatedClassesDir}/pairs1</destDir>
-                          <makePairs>true</makePairs>
-                          <usePkgPath>true</usePkgPath>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>pairs2</id>
-                        <goals>
-                            <goal>cgen</goal>
-                        </goals>
-                        <configuration>
-                          <map>${testResourceDir}/testmap.map.xml</map>
-                          <destDir>${generatedClassesDir}/pairs2</destDir>
-                          <makePairs>true</makePairs>
-                          <usePkgPath>false</usePkgPath>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>pairs3</id>
-                        <goals>
-                            <goal>cgen</goal>
-                        </goals>
-                        <configuration>
-                          <map>${testResourceDir}/testmap.map.xml</map>
-                          <destDir>${generatedClassesDir}/pairs3</destDir>
-                          <makePairs>true</makePairs>
-                          <usePkgPath>true</usePkgPath>
-                          <superPkg>org.apache.cayenne.testdo.testmap.superart</superPkg>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>pairs1-client</id>
-                        <goals>
-                            <goal>cgen</goal>
-                        </goals>
-                        <configuration>
-                          <map>${testResourceDir}/testmap-client.map.xml</map>
-                          <destDir>${generatedClassesDir}/pairs1-client</destDir>
-                          <client>true</client>
-                          <makePairs>true</makePairs>
-                          <usePkgPath>true</usePkgPath>
-                          <superPkg>org.apache.cayenne.testdo.testmap.client.superart</superPkg>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>pairs-embeddables3</id>
-                        <goals>
-                            <goal>cgen</goal>
-                        </goals>
-                        <configuration>
-                          <map>${testResourceDir}/embeddable.map.xml</map>
-                          <destDir>${generatedClassesDir}/pairs-embeddables3</destDir>
-                          <makePairs>true</makePairs>
-                          <usePkgPath>true</usePkgPath>
-                          <superPkg>org.apache.cayenne.testdo.embeddable.auto</superPkg>
-                        </configuration>
-                    </execution>
-				</executions>
-            </plugin>
-		</plugins>
-	</build>
-</project>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/cayenne-tools-itest/src/test/java/org/apache/cayenne/tools/CayenneGeneratorIntegrationTest.java
----------------------------------------------------------------------
diff --git a/itests/cayenne-tools-itest/src/test/java/org/apache/cayenne/tools/CayenneGeneratorIntegrationTest.java b/itests/cayenne-tools-itest/src/test/java/org/apache/cayenne/tools/CayenneGeneratorIntegrationTest.java
deleted file mode 100644
index 2142389..0000000
--- a/itests/cayenne-tools-itest/src/test/java/org/apache/cayenne/tools/CayenneGeneratorIntegrationTest.java
+++ /dev/null
@@ -1,186 +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.tools;
-
-import org.junit.Test;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStreamReader;
-import java.util.regex.Pattern;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-public class CayenneGeneratorIntegrationTest {
-
-    private File testDir;
-
-    private void startTest(String testName) {
-        testDir = new File("target/generated-tests", testName);
-        assertTrue(testDir.isDirectory());
-    }
-
-    /**
-     * Test single classes with a non-standard template.
-     */
-    @Test
-    public void testSingleClassesCustTemplate() throws Exception {
-        startTest("single-classes-cust-template");
-
-        assertContents("org/apache/cayenne/testdo/testmap/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap",
-                "CayenneDataObject");
-        assertExists("org/apache/cayenne/testdo/testmap/_Artist.java");
-    }
-
-    /** Test single classes generation including full package path. */
-    @Test
-    public void testSingleClasses1() throws Exception {
-        startTest("single-classes1");
-
-        assertContents("org/apache/cayenne/testdo/testmap/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap",
-                "BaseDataObject");
-        assertExists("org/apache/cayenne/testdo/testmap/_Artist.java");
-    }
-
-    /** Test single classes generation ignoring package path. */
-    @Test
-    public void testSingleClasses2() throws Exception {
-        startTest("single-classes2");
-
-        assertContents("Artist.java", "Artist", "org.apache.cayenne.testdo.testmap", "BaseDataObject");
-        assertExists("_Artist.java");
-        assertExists("org/apache/cayenne/testdo/testmap/Artist.java");
-    }
-
-    /** Test pairs generation including full package path. */
-    @Test
-    public void testPairs1() throws Exception {
-        startTest("pairs1");
-
-        assertContents("org/apache/cayenne/testdo/testmap/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap",
-                "_Artist");
-        assertContents("org/apache/cayenne/testdo/testmap/auto/_Artist.java", "_Artist",
-                "org.apache.cayenne.testdo.testmap.auto", "BaseDataObject");
-    }
-
-    /** Test pairs generation in the same directory. */
-    @Test
-    public void testPairs2() throws Exception {
-        startTest("pairs2");
-
-        assertContents("Artist.java", "Artist", "org.apache.cayenne.testdo.testmap", "_Artist");
-        assertContents("_Artist.java", "_Artist", "org.apache.cayenne.testdo.testmap", "BaseDataObject");
-        assertExists("org/apache/cayenne/testdo/testmap/Artist.java");
-    }
-
-    /**
-     * Test pairs generation including full package path with superclass and
-     * subclass in different packages.
-     */
-    @Test
-    public void testPairs3() throws Exception {
-        startTest("pairs3");
-
-        assertContents("org/apache/cayenne/testdo/testmap/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap",
-                "_Artist");
-        assertContents("org/apache/cayenne/testdo/testmap/superart/_Artist.java", "_Artist",
-                "org.apache.cayenne.testdo.testmap.superart", "BaseDataObject");
-    }
-
-    @Test
-    public void testPairs1_client() throws Exception {
-        startTest("pairs1-client");
-
-        assertContents("org/apache/cayenne/testdo/testmap/client/Artist.java", "Artist", "org.apache.cayenne.testdo.testmap.client",
-                "_Artist");
-        assertContents("org/apache/cayenne/testdo/testmap/client/superart/_Artist.java", "_Artist",
-                "org.apache.cayenne.testdo.testmap.client.superart", "PersistentObject");
-    }
-
-    @Test
-    public void testPairsEmbeddable3() throws Exception {
-        startTest("pairs-embeddables3");
-
-        assertContents("org/apache/cayenne/testdo/embeddable/EmbedEntity1.java", "EmbedEntity1",
-                "org.apache.cayenne.testdo.embeddable", "_EmbedEntity1");
-        assertContents("org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity1.java", "_EmbedEntity1",
-                "org.apache.cayenne.testdo.embeddable.auto", "BaseDataObject");
-        assertContents("org/apache/cayenne/testdo/embeddable/Embeddable1.java", "Embeddable1",
-                "org.apache.cayenne.testdo.embeddable", "_Embeddable1");
-        assertContents("org/apache/cayenne/testdo/embeddable/auto/_Embeddable1.java", "_Embeddable1",
-                "org.apache.cayenne.testdo.embeddable.auto", "Object");
-    }
-
-    private String convertPath(String unixPath) {
-        return unixPath.replace('/', File.separatorChar);
-    }
-
-    private void assertContents(String filePath, String className, String packageName, String extendsName)
-            throws Exception {
-        File f = new File(testDir, convertPath(filePath));
-        assertTrue("Not a file: " + f.getAbsolutePath(), f.isFile());
-        assertContents(f, className, packageName, extendsName);
-    }
-
-    private void assertExists(String filePath) {
-        File f = new File(testDir, convertPath(filePath));
-        assertFalse(f.exists());
-    }
-
-    private void assertContents(File f, String className, String packageName, String extendsName) throws Exception {
-        
-        try(BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(f)))) {
-            assertPackage(in, packageName);
-            assertClass(in, className, extendsName);
-        } 
-    }
-
-    private void assertPackage(BufferedReader in, String packageName) throws Exception {
-
-        String s = null;
-        while ((s = in.readLine()) != null) {
-            if (Pattern.matches("^package\\s+([^\\s;]+);", s)) {
-                assertTrue(s.indexOf(packageName) > 0);
-                return;
-            }
-        }
-
-        fail("No package declaration found.");
-    }
-
-    private void assertClass(BufferedReader in, String className, String extendsName) throws Exception {
-
-        Pattern classPattern = Pattern.compile("^public\\s+");
-
-        String s = null;
-        while ((s = in.readLine()) != null) {
-            if (classPattern.matcher(s).find()) {
-                assertTrue(s.indexOf(className) > 0);
-                assertTrue(s.indexOf(extendsName) > 0);
-                assertTrue(s.indexOf(className) < s.indexOf(extendsName));
-                return;
-            }
-        }
-
-        fail("No class declaration found.");
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/cayenne-tools-itest/src/test/resources/cayenne-client.xml
----------------------------------------------------------------------
diff --git a/itests/cayenne-tools-itest/src/test/resources/cayenne-client.xml b/itests/cayenne-tools-itest/src/test/resources/cayenne-client.xml
deleted file mode 100644
index 355ac28..0000000
--- a/itests/cayenne-tools-itest/src/test/resources/cayenne-client.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<domain xmlns="http://cayenne.apache.org/schema/10/domain"
-	 project-version="10">
-	<map name="testmap-client"/>
-</domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/cayenne-tools-itest/src/test/resources/embeddable.map.xml
----------------------------------------------------------------------
diff --git a/itests/cayenne-tools-itest/src/test/resources/embeddable.map.xml b/itests/cayenne-tools-itest/src/test/resources/embeddable.map.xml
deleted file mode 100644
index 10c4db6..0000000
--- a/itests/cayenne-tools-itest/src/test/resources/embeddable.map.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
-	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd"
-	 project-version="10">
-	<property name="defaultPackage" value="org.apache.cayenne.testdo.embeddable"/>
-	<embeddable className="org.apache.cayenne.testdo.embeddable.Embeddable1">
-		<embeddable-attribute name="embedded10" type="java.lang.String" db-attribute-name="EMBEDDED10"/>
-		<embeddable-attribute name="embedded20" type="java.lang.String" db-attribute-name="EMBEDDED20"/>
-	</embeddable>
-	<db-entity name="EMBED_ENTITY1">
-		<db-attribute name="EMBEDDED10" type="VARCHAR" length="100"/>
-		<db-attribute name="EMBEDDED20" type="VARCHAR" length="100"/>
-		<db-attribute name="EMBEDDED30" type="VARCHAR" length="100"/>
-		<db-attribute name="EMBEDDED40" type="VARCHAR" length="100"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-	</db-entity>
-	<obj-entity name="EmbedEntity1" className="org.apache.cayenne.testdo.embeddable.EmbedEntity1" dbEntityName="EMBED_ENTITY1">
-		<embedded-attribute name="embedded1" type="org.apache.cayenne.testdo.embeddable.Embeddable1"/>
-		<embedded-attribute name="embedded2" type="org.apache.cayenne.testdo.embeddable.Embeddable1">
-			<embeddable-attribute-override name="embedded10" db-attribute-path="EMBEDDED30"/>
-			<embeddable-attribute-override name="embedded20" db-attribute-path="EMBEDDED40"/>
-		</embedded-attribute>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-</data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen-dependent.map.xml
----------------------------------------------------------------------
diff --git a/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen-dependent.map.xml b/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen-dependent.map.xml
deleted file mode 100644
index b72f320..0000000
--- a/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen-dependent.map.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<data-map xmlns="http://cayenne.apache.org/schema/9/modelMap"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://cayenne.apache.org/schema/9/modelMap http://cayenne.apache.org/schema/9/modelMap.xsd"
-	project-version="1.1">
-	<property name="defaultPackage" value="org.apache.cayenne.testdo.cgen2"/>
-	<db-entity name="MYARTGROUP">
-		<db-attribute name="MY_GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="CUSTOM" type="VARCHAR" isMandatory="true" length="100"/>
-		<db-attribute name="MY_PARENT_GROUP_ID" type="INTEGER"/>
-	</db-entity>
-	<obj-entity name="MyArtGroup" className="org.apache.cayenne.testdo.cgen2.MyArtGroup" dbEntityName="MYARTGROUP">
-		<obj-attribute name="custom" type="java.lang.String" db-attribute-path="CUSTOM"/>
-	</obj-entity>
-	<db-relationship name="toParentArtGroup" source="MYARTGROUP" target="ARTGROUP" toMany="false">
-		<db-attribute-pair source="MY_PARENT_GROUP_ID" target="GROUP_ID"/>
-	</db-relationship>
-	<obj-relationship name="toParentGroup" source="MyArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toParentArtGroup"/>
-</data-map>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen.map.xml
----------------------------------------------------------------------
diff --git a/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen.map.xml b/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen.map.xml
deleted file mode 100644
index 56a2d92..0000000
--- a/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/cgen.map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<data-map xmlns="http://cayenne.apache.org/schema/9/modelMap"
-	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	 xsi:schemaLocation="http://cayenne.apache.org/schema/9/modelMap http://cayenne.apache.org/schema/9/modelMap.xsd"
-	 project-version="9">
-
-	<db-entity name="ARTGROUP">
-		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" isMandatory="true" length="100"/>
-		<db-attribute name="PARENT_GROUP_ID" type="INTEGER"/>
-	</db-entity>
-	<obj-entity name="ArtGroup" className="org.apache.cayenne.testdo.testmap.ArtGroup" dbEntityName="ARTGROUP">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-</data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/velotemplate.vm
----------------------------------------------------------------------
diff --git a/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/velotemplate.vm b/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/velotemplate.vm
deleted file mode 100644
index 1ca078c..0000000
--- a/itests/cayenne-tools-itest/src/test/resources/org/apache/cayenne/tools/velotemplate.vm
+++ /dev/null
@@ -1,13 +0,0 @@
-## Test Velocity template
-${importUtils.setPackage($subPackageName)}##
-${importUtils.generate()}
-
-import java.util.List;
-import org.apache.cayenne.*;
-
-/** Class ${classGen.superPrefix}${classGen.className} was generated by Cayenne.
-  * It is probably a good idea to avoid changing this class manually, 
-  * since it may be overwritten next time code is regenerated. 
-  * If you need to make any customizations, please use subclass. 
-  */
-public class ${subClassName} extends CayenneDataObject {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6378c41f/itests/cayenne-tools-itest/src/test/resources/testmap-client.map.xml
----------------------------------------------------------------------
diff --git a/itests/cayenne-tools-itest/src/test/resources/testmap-client.map.xml b/itests/cayenne-tools-itest/src/test/resources/testmap-client.map.xml
deleted file mode 100644
index 87145d5..0000000
--- a/itests/cayenne-tools-itest/src/test/resources/testmap-client.map.xml
+++ /dev/null
@@ -1,730 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
-	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd"
-	 project-version="10">
-	<property name="defaultPackage" value="org.apache.cayenne.testdo.testmap"/>
-	<property name="defaultSuperclass" value="org.apache.cayenne.CayenneDataObject"/>
-	<property name="clientSupported" value="true"/>
-	<property name="defaultClientPackage" value="org.apache.cayenne.testdo.testmap.client"/>
-	<property name="defaultClientSuperclass" value="org.apache.cayenne.PersistentObject"/>
-	<procedure name="cayenne_tst_out_proc">
-		<procedure-parameter name="in_param" type="INTEGER" direction="in"/>
-		<procedure-parameter name="out_param" type="INTEGER" direction="out"/>
-	</procedure>
-	<procedure name="cayenne_tst_select_proc">
-		<procedure-parameter name="aName" type="VARCHAR" length="254" direction="in"/>
-		<procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
-	</procedure>
-	<procedure name="cayenne_tst_upd_proc">
-		<procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
-	</procedure>
-	<procedure name="cayenne_tst_upd_proc2"/>
-	<db-entity name="ARRAYS_ENTITY">
-		<db-attribute name="BYTE_ARRAY" type="VARBINARY" length="200"/>
-		<db-attribute name="BYTE_WRAPPER_ARRAY" type="VARBINARY" length="200"/>
-		<db-attribute name="CHAR_ARRAY" type="VARCHAR" length="200"/>
-		<db-attribute name="CHAR_WRAPPER_ARRAY" type="VARCHAR" length="200"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="ARTGROUP">
-		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" isMandatory="true" length="100"/>
-		<db-attribute name="PARENT_GROUP_ID" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="ARTIST">
-		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
-		<db-attribute name="DATE_OF_BIRTH" type="DATE"/>
-	</db-entity>
-	<db-entity name="ARTIST_CT">
-		<db-attribute name="ARTIST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
-		<db-attribute name="DATE_OF_BIRTH" type="DATE"/>
-	</db-entity>
-	<db-entity name="ARTIST_EXHIBIT">
-		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="ARTIST_GROUP">
-		<db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BIGDECIMAL_ENTITY">
-		<db-attribute name="BIGDECIMAL_FIELD" type="NUMERIC" length="12" scale="2"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BIGINTEGER_ENTITY">
-		<db-attribute name="BIG_INTEGER_FIELD" type="BIGINT"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BINARY_PK_TEST1">
-		<db-attribute name="BIN_ID" type="VARBINARY" isPrimaryKey="true" isMandatory="true" length="32"/>
-		<db-attribute name="NAME" type="VARCHAR" length="10"/>
-	</db-entity>
-	<db-entity name="BINARY_PK_TEST2">
-		<db-attribute name="DETAIL_NAME" type="VARCHAR" length="10"/>
-		<db-attribute name="FK_ID" type="VARBINARY" length="32"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BIT_TEST">
-		<db-attribute name="BIT_COLUMN" type="BIT" isMandatory="true"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BLOB_TEST">
-		<db-attribute name="BLOB_COL" type="BLOB"/>
-		<db-attribute name="BLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="BOOLEAN_TEST">
-		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN" isMandatory="true"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CALENDAR_TEST">
-		<db-attribute name="CALENDAR_FIELD" type="TIMESTAMP"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CHARACTER_ENTITY">
-		<db-attribute name="CHARACTER_FIELD" type="CHAR" length="1"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CHAR_FK_TEST">
-		<db-attribute name="FK_COL" type="CHAR" length="10"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-		<db-attribute name="PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CHAR_PK_TEST">
-		<db-attribute name="OTHER_COL" type="CHAR" length="10"/>
-		<db-attribute name="PK_COL" type="CHAR" isPrimaryKey="true" isMandatory="true" length="10"/>
-	</db-entity>
-	<db-entity name="CLOB_TEST">
-		<db-attribute name="CLOB_COL" type="CLOB"/>
-		<db-attribute name="CLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="CLOB_TEST_RELATION">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="ID_CLOB" type="INTEGER" isMandatory="true"/>
-		<db-attribute name="VALUE" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="COMPOUND_FK_TEST">
-		<db-attribute name="F_KEY1" type="VARCHAR" length="20"/>
-		<db-attribute name="F_KEY2" type="VARCHAR" length="20"/>
-		<db-attribute name="NAME" type="VARCHAR" length="255"/>
-		<db-attribute name="PKEY" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="COMPOUND_PK_TEST">
-		<db-attribute name="KEY1" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
-		<db-attribute name="KEY2" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
-		<db-attribute name="NAME" type="VARCHAR" length="255"/>
-	</db-entity>
-	<db-entity name="DATE_TEST">
-		<db-attribute name="DATE_COLUMN" type="DATE"/>
-		<db-attribute name="DATE_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
-		<db-attribute name="TIME_COLUMN" type="TIME"/>
-	</db-entity>
-	<db-entity name="DECIMAL_PK_TST">
-		<db-attribute name="DECIMAL_PK" type="DECIMAL" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-	</db-entity>
-	<db-entity name="ENUM_ENTITY">
-		<db-attribute name="ENUM_ATTRIBUTE" type="VARCHAR" length="250"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="EXHIBIT">
-		<db-attribute name="CLOSING_DATE" type="TIMESTAMP" isMandatory="true"/>
-		<db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="GALLERY_ID" type="INTEGER" isMandatory="true"/>
-		<db-attribute name="OPENING_DATE" type="TIMESTAMP" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="EXTENDED_TYPE_TEST">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="200"/>
-	</db-entity>
-	<db-entity name="FLOAT_TEST">
-		<db-attribute name="FLOAT_COL" type="FLOAT"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="GALLERY">
-		<db-attribute name="GALLERY_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="GALLERY_NAME" type="VARCHAR" isMandatory="true" length="100"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_COMP_KEY">
-		<db-attribute name="AUTO_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-		<db-attribute name="PROPAGATED_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_COMP_M">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_DEP">
-		<db-attribute name="GENERATED_COLUMN_FK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_TEST">
-		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="250"/>
-	</db-entity>
-	<db-entity name="GENERATED_COLUMN_TEST2">
-		<db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
-	</db-entity>
-	<db-entity name="GENERATED_F1">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="GENERATED_F2">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="GENERATED_JOIN">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
-		<db-attribute name="ID1" type="INTEGER"/>
-		<db-attribute name="ID2" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="LONG_ENTITY">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="LONG_FIELD" type="BIGINT"/>
-	</db-entity>
-	<db-entity name="MEANINGFUL_PK_DEP">
-		<db-attribute name="DESCR" type="VARCHAR" length="50"/>
-		<db-attribute name="MASTER_PK" type="INTEGER"/>
-		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="MEANINGFUL_PK_TEST1">
-		<db-attribute name="DESCR" type="VARCHAR" length="50"/>
-		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-	</db-entity>
-	<db-entity name="MIXED_PERSISTENCE_STRATEGY">
-		<db-attribute name="DESCRIPTION" type="VARCHAR" length="200"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="200"/>
-	</db-entity>
-	<db-entity name="MIXED_PERSISTENCE_STRATEGY2">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="MASTER_ID" type="INTEGER"/>
-		<db-attribute name="NAME" type="VARCHAR" length="200"/>
-	</db-entity>
-	<db-entity name="NO_PK_TEST">
-		<db-attribute name="ATTRIBUTE1" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="PAINTING">
-		<db-attribute name="ARTIST_ID" type="BIGINT"/>
-		<db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
-		<db-attribute name="GALLERY_ID" type="INTEGER"/>
-		<db-attribute name="PAINTING_DESCRIPTION" type="VARCHAR" length="255"/>
-		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
-	</db-entity>
-	<db-entity name="PAINTING1">
-		<db-attribute name="ARTIST_ID" type="BIGINT"/>
-		<db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
-		<db-attribute name="GALLERY_ID" type="INTEGER"/>
-		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
-	</db-entity>
-	<db-entity name="PAINTING_INFO">
-		<db-attribute name="IMAGE_BLOB" type="LONGVARBINARY"/>
-		<db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="TEXT_REVIEW" type="LONGVARCHAR"/>
-	</db-entity>
-	<db-entity name="PRIMITIVES_TEST">
-		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="INT_COLUMN" type="INTEGER"/>
-	</db-entity>
-	<db-entity name="SERIALIZABLE_ENTITY">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="SERIALIZABLE_FIELD" type="BLOB"/>
-	</db-entity>
-	<db-entity name="SMALLINT_TEST">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="SMALLINT_COL" type="SMALLINT"/>
-	</db-entity>
-	<db-entity name="TINYINT_TEST">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="TINYINT_COL" type="TINYINT"/>
-	</db-entity>
-	<db-entity name="TYPES_MAPPING_TEST1">
-		<db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="BIGINT_COLUMN" type="BIGINT"/>
-		<db-attribute name="BIT_COLUMN" type="BIT"/>
-		<db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
-		<db-attribute name="CHAR_COLUMN" type="CHAR" length="254"/>
-		<db-attribute name="CLOB_COLUMN" type="CLOB"/>
-		<db-attribute name="DATE_COLUMN" type="DATE"/>
-		<db-attribute name="DECIMAL_COLUMN" type="DECIMAL" length="12" scale="5"/>
-		<db-attribute name="DOUBLE_COLUMN" type="DOUBLE" scale="7"/>
-		<db-attribute name="FLOAT_COLUMN" type="FLOAT" scale="3"/>
-		<db-attribute name="INTEGER_COLUMN" type="INTEGER"/>
-		<db-attribute name="LONGVARCHAR_COLUMN" type="LONGVARCHAR"/>
-		<db-attribute name="NUMERIC_COLUMN" type="NUMERIC" length="12" scale="5"/>
-		<db-attribute name="REAL_COLUMN" type="REAL" scale="5"/>
-		<db-attribute name="SMALLINT_COLUMN" type="SMALLINT"/>
-		<db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
-		<db-attribute name="TIME_COLUMN" type="TIME"/>
-		<db-attribute name="TINYINT_COLUMN" type="TINYINT"/>
-		<db-attribute name="VARCHAR_COLUMN" type="VARCHAR" length="255"/>
-	</db-entity>
-	<db-entity name="TYPES_MAPPING_TEST2">
-		<db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="BINARY_COLUMN" type="BINARY" length="14"/>
-		<db-attribute name="BLOB_COLUMN" type="BLOB"/>
-		<db-attribute name="LONGVARBINARY_COLUMN" type="LONGVARBINARY"/>
-		<db-attribute name="VARBINARY_COLUMN" type="VARBINARY" length="1000"/>
-	</db-entity>
-	<db-entity name="UUID_TEST">
-		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="UUID" type="VARCHAR" length="100"/>
-	</db-entity>
-	<obj-entity name="ArraysEntity" className="org.apache.cayenne.testdo.misc_types.ArraysEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.ArraysEntity" dbEntityName="ARRAYS_ENTITY">
-		<obj-attribute name="byteArray" type="byte[]" db-attribute-path="BYTE_ARRAY"/>
-		<obj-attribute name="byteWrapperArray" type="java.lang.Byte[]" db-attribute-path="BYTE_WRAPPER_ARRAY"/>
-		<obj-attribute name="charArray" type="char[]" db-attribute-path="CHAR_ARRAY"/>
-		<obj-attribute name="charWrapperArray" type="java.lang.Character[]" db-attribute-path="CHAR_WRAPPER_ARRAY"/>
-	</obj-entity>
-	<obj-entity name="ArtGroup" className="org.apache.cayenne.testdo.testmap.ArtGroup" clientClassName="org.apache.cayenne.testdo.testmap.client.ArtGroup" dbEntityName="ARTGROUP">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="Artist" className="org.apache.cayenne.testdo.testmap.Artist" clientClassName="org.apache.cayenne.testdo.testmap.client.Artist" dbEntityName="ARTIST">
-		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
-		<obj-attribute name="dateOfBirth" type="java.util.Date" db-attribute-path="DATE_OF_BIRTH"/>
-	</obj-entity>
-	<obj-entity name="ArtistCallbackTest" className="org.apache.cayenne.testdo.testmap.ArtistCallbackTest" clientClassName="org.apache.cayenne.testdo.testmap.client.ArtistCallbackTest" dbEntityName="ARTIST_CT">
-		<obj-attribute name="artistName" type="java.lang.String"/>
-		<obj-attribute name="dateOfBirth" type="java.util.Date"/>
-		<post-add method-name="prePersistEntityObjEntity"/>
-		<post-persist method-name="postPersistEntityObjEntity"/>
-		<pre-update method-name="preUpdateEntityObjEntity"/>
-		<post-update method-name="postUpdateEntityObjEntity"/>
-		<pre-remove method-name="preRemoveEntityObjEntity"/>
-		<post-remove method-name="postRemoveEntityObjEntity"/>
-		<post-load method-name="postLoadEntityObjEntity"/>
-	</obj-entity>
-	<obj-entity name="ArtistExhibit" className="org.apache.cayenne.testdo.testmap.ArtistExhibit" clientClassName="org.apache.cayenne.testdo.testmap.client.ArtistExhibit" dbEntityName="ARTIST_EXHIBIT"/>
-	<obj-entity name="BigDecimalEntity" className="org.apache.cayenne.testdo.numeric_types.BigDecimalEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BigDecimalEntity" dbEntityName="BIGDECIMAL_ENTITY">
-		<obj-attribute name="bigDecimalField" type="java.math.BigDecimal" db-attribute-path="BIGDECIMAL_FIELD"/>
-	</obj-entity>
-	<obj-entity name="BigIntegerEntity" className="org.apache.cayenne.testdo.numeric_types.BigIntegerEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BigIntegerEntity" dbEntityName="BIGINTEGER_ENTITY">
-		<obj-attribute name="bigIntegerField" type="java.math.BigInteger" db-attribute-path="BIG_INTEGER_FIELD"/>
-	</obj-entity>
-	<obj-entity name="BinaryPKTest1" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest1" clientClassName="org.apache.cayenne.testdo.testmap.client.BinaryPKTest1" dbEntityName="BINARY_PK_TEST1">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="BinaryPKTest2" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest2" clientClassName="org.apache.cayenne.testdo.testmap.client.BinaryPKTest2" dbEntityName="BINARY_PK_TEST2">
-		<obj-attribute name="detailName" type="java.lang.String" db-attribute-path="DETAIL_NAME"/>
-	</obj-entity>
-	<obj-entity name="BitNumberTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitNumberTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BitNumberTestEntity" dbEntityName="BIT_TEST">
-		<obj-attribute name="bitColumn" type="java.lang.Integer" db-attribute-path="BIT_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="BitTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BitTestEntity" dbEntityName="BIT_TEST">
-		<obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="BlobTestEntity" className="org.apache.cayenne.testdo.lob.BlobTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BlobTestEntity" dbEntityName="BLOB_TEST">
-		<obj-attribute name="blobCol" type="byte[]" db-attribute-path="BLOB_COL"/>
-	</obj-entity>
-	<obj-entity name="BooleanTestEntity" className="org.apache.cayenne.testdo.numeric_types.BooleanTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.BooleanTestEntity" dbEntityName="BOOLEAN_TEST">
-		<obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="CalendarEntity" className="org.apache.cayenne.testdo.date_time.CalendarEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CalendarEntity" dbEntityName="CALENDAR_TEST">
-		<obj-attribute name="calendarField" type="java.util.Calendar" db-attribute-path="CALENDAR_FIELD"/>
-	</obj-entity>
-	<obj-entity name="CharFkTestEntity" className="org.apache.cayenne.testdo.compound.CharFkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CharFkTestEntity" dbEntityName="CHAR_FK_TEST">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="CharPkTestEntity" className="org.apache.cayenne.testdo.compound.CharPkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CharPkTestEntity" dbEntityName="CHAR_PK_TEST">
-		<obj-attribute name="otherCol" type="java.lang.String" db-attribute-path="OTHER_COL"/>
-		<obj-attribute name="pkCol" type="java.lang.String" db-attribute-path="PK_COL"/>
-	</obj-entity>
-	<obj-entity name="CharacterEntity" className="org.apache.cayenne.testdo.misc_types.CharacterEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CharacterEntity" dbEntityName="CHARACTER_ENTITY">
-		<obj-attribute name="characterField" type="java.lang.Character" db-attribute-path="CHARACTER_FIELD"/>
-	</obj-entity>
-	<obj-entity name="ClobTestEntity" className="org.apache.cayenne.testdo.lob.ClobTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.ClobTestEntity" dbEntityName="CLOB_TEST">
-		<obj-attribute name="clobCol" type="java.lang.String" db-attribute-path="CLOB_COL"/>
-	</obj-entity>
-	<obj-entity name="ClobTestRelation" className="org.apache.cayenne.testdo.lob.ClobTestRelation" clientClassName="org.apache.cayenne.testdo.testmap.client.ClobTestRelation" dbEntityName="CLOB_TEST_RELATION">
-		<obj-attribute name="id" type="java.lang.Integer" db-attribute-path="ID"/>
-		<obj-attribute name="value" type="java.lang.Integer" db-attribute-path="VALUE"/>
-	</obj-entity>
-	<obj-entity name="CompoundFkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundFkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CompoundFkTestEntity" dbEntityName="COMPOUND_FK_TEST">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="CompoundPainting" className="org.apache.cayenne.testdo.testmap.CompoundPainting" clientClassName="org.apache.cayenne.testdo.testmap.client.CompoundPainting" dbEntityName="PAINTING">
-		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="toArtist.ARTIST_NAME"/>
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="toGallery.GALLERY_NAME"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
-	</obj-entity>
-	<obj-entity name="CompoundPkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundPkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.CompoundPkTestEntity" dbEntityName="COMPOUND_PK_TEST">
-		<obj-attribute name="key1" type="java.lang.String" db-attribute-path="KEY1"/>
-		<obj-attribute name="key2" type="java.lang.String" db-attribute-path="KEY2"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="DateTestEntity" className="org.apache.cayenne.testdo.date_time.DateTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.DateTestEntity" dbEntityName="DATE_TEST">
-		<obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
-		<obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
-		<obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="DecimalPKTest1" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTest1" clientClassName="org.apache.cayenne.testdo.testmap.client.DecimalPKTest1" dbEntityName="DECIMAL_PK_TST">
-		<obj-attribute name="decimalPK" type="java.lang.Double" db-attribute-path="DECIMAL_PK"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="DecimalPKTestEntity" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.DecimalPKTestEntity" dbEntityName="DECIMAL_PK_TST">
-		<obj-attribute name="decimalPK" type="java.math.BigDecimal" db-attribute-path="DECIMAL_PK"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="EnumEntity" className="org.apache.cayenne.testdo.enum_test.EnumEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.EnumEntity" dbEntityName="ENUM_ENTITY">
-		<obj-attribute name="enumAttribute" type="org.apache.cayenne.testdo.enum_test.Enum1" db-attribute-path="ENUM_ATTRIBUTE"/>
-	</obj-entity>
-	<obj-entity name="Exhibit" className="org.apache.cayenne.testdo.testmap.Exhibit" clientClassName="org.apache.cayenne.testdo.testmap.client.Exhibit" dbEntityName="EXHIBIT">
-		<obj-attribute name="closingDate" type="java.util.Date" db-attribute-path="CLOSING_DATE"/>
-		<obj-attribute name="openingDate" type="java.util.Date" db-attribute-path="OPENING_DATE"/>
-	</obj-entity>
-	<obj-entity name="ExtendedTypeEntity" className="org.apache.cayenne.testdo.extended_type.ExtendedTypeEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.ExtendedTypeEntity" dbEntityName="EXTENDED_TYPE_TEST">
-		<obj-attribute name="name" type="org.apache.cayenne.testdo.extended_type.StringET1" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="Gallery" className="org.apache.cayenne.testdo.testmap.Gallery" clientClassName="org.apache.cayenne.testdo.testmap.client.Gallery" dbEntityName="GALLERY">
-		<obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="GALLERY_NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnCompKey" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompKey" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnCompKey" dbEntityName="GENERATED_COLUMN_COMP_KEY">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnCompMaster" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompMaster" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnCompMaster" dbEntityName="GENERATED_COLUMN_COMP_M">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnDep" className="org.apache.cayenne.testdo.generated.GeneratedColumnDep" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnDep" dbEntityName="GENERATED_COLUMN_DEP">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnTest2" className="org.apache.cayenne.testdo.generated.GeneratedColumnTest2" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnTest2" dbEntityName="GENERATED_COLUMN_TEST2">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedColumnTestEntity" className="org.apache.cayenne.testdo.generated.GeneratedColumnTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="GeneratedF1" className="org.apache.cayenne.testdo.generated.GeneratedF1" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedF1" dbEntityName="GENERATED_F1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject"/>
-	<obj-entity name="GeneratedF2" className="org.apache.cayenne.testdo.generated.GeneratedF2" clientClassName="org.apache.cayenne.testdo.testmap.client.GeneratedF2" dbEntityName="GENERATED_F2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject"/>
-	<obj-entity name="LongEntity" className="org.apache.cayenne.testdo.numeric_types.LongEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.LongEntity" dbEntityName="LONG_ENTITY">
-		<obj-attribute name="longField" type="java.lang.Long" db-attribute-path="LONG_FIELD"/>
-	</obj-entity>
-	<obj-entity name="MeaningfulGeneratedColumnTestEntity" className="org.apache.cayenne.testdo.testmap.MeaningfulGeneratedColumnTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.MeaningfulGeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
-		<obj-attribute name="generatedColumn" type="java.lang.Integer" db-attribute-path="GENERATED_COLUMN"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="MeaningfulPKDep" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKDep" clientClassName="org.apache.cayenne.testdo.testmap.client.MeaningfulPKDep" dbEntityName="MEANINGFUL_PK_DEP">
-		<obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
-	</obj-entity>
-	<obj-entity name="MeaningfulPKTest1" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKTest1" clientClassName="org.apache.cayenne.testdo.testmap.client.MeaningfulPKTest1" dbEntityName="MEANINGFUL_PK_TEST1">
-		<obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
-		<obj-attribute name="pkAttribute" type="java.lang.Integer" db-attribute-path="PK_ATTRIBUTE"/>
-	</obj-entity>
-	<obj-entity name="MixedPersistenceStrategy" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy" clientClassName="org.apache.cayenne.testdo.testmap.client.MixedPersistenceStrategy" dbEntityName="MIXED_PERSISTENCE_STRATEGY">
-		<obj-attribute name="description" type="java.lang.String" db-attribute-path="DESCRIPTION"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="MixedPersistenceStrategy2" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy2" clientClassName="org.apache.cayenne.testdo.testmap.client.MixedPersistenceStrategy2" dbEntityName="MIXED_PERSISTENCE_STRATEGY2">
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
-	</obj-entity>
-	<obj-entity name="NoPkTestEntity" className="org.apache.cayenne.testdo.no_pk.NoPkTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.NoPkTestEntity" dbEntityName="NO_PK_TEST">
-		<obj-attribute name="attribute1" type="java.lang.Integer" db-attribute-path="ATTRIBUTE1"/>
-	</obj-entity>
-	<obj-entity name="Painting" className="org.apache.cayenne.testdo.testmap.Painting" clientClassName="org.apache.cayenne.testdo.testmap.client.Painting" dbEntityName="PAINTING" superClassName="org.apache.cayenne.testdo.testmap.ArtDataObject">
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="paintingDescription" type="java.lang.String" db-attribute-path="PAINTING_DESCRIPTION"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-	</obj-entity>
-	<obj-entity name="Painting1" className="org.apache.cayenne.testdo.testmap.Painting1" clientClassName="org.apache.cayenne.testdo.testmap.client.Painting1" dbEntityName="PAINTING1">
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-	</obj-entity>
-	<obj-entity name="PaintingInfo" className="org.apache.cayenne.testdo.testmap.PaintingInfo" clientClassName="org.apache.cayenne.testdo.testmap.client.PaintingInfo" dbEntityName="PAINTING_INFO">
-		<obj-attribute name="imageBlob" type="byte[]" db-attribute-path="IMAGE_BLOB"/>
-		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="TEXT_REVIEW"/>
-	</obj-entity>
-	<obj-entity name="PrimitivesTestEntity" className="org.apache.cayenne.testdo.primitive.PrimitivesTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.PrimitivesTestEntity" dbEntityName="PRIMITIVES_TEST">
-		<obj-attribute name="booleanColumn" type="boolean" db-attribute-path="BOOLEAN_COLUMN"/>
-		<obj-attribute name="intColumn" type="int" db-attribute-path="INT_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="ROArtist" className="org.apache.cayenne.testdo.testmap.ROArtist" clientClassName="org.apache.cayenne.testdo.testmap.client.ROArtist" readOnly="true" dbEntityName="ARTIST">
-		<obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
-		<obj-attribute name="dateOfBirth" type="java.sql.Date" db-attribute-path="DATE_OF_BIRTH"/>
-	</obj-entity>
-	<obj-entity name="ROPainting" className="org.apache.cayenne.testdo.testmap.ROPainting" clientClassName="org.apache.cayenne.testdo.testmap.client.ROPainting" readOnly="true" dbEntityName="PAINTING">
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-	</obj-entity>
-	<obj-entity name="RWCompoundPainting" className="org.apache.cayenne.testdo.testmap.RWCompoundPainting" clientClassName="org.apache.cayenne.testdo.testmap.client.RWCompoundPainting" dbEntityName="PAINTING">
-		<obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-		<obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
-	</obj-entity>
-	<obj-entity name="ReturnTypesMap1" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap1" clientClassName="org.apache.cayenne.testdo.testmap.client.ReturnTypesMap1" dbEntityName="TYPES_MAPPING_TEST1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
-		<obj-attribute name="bigintColumn" type="java.lang.Long" db-attribute-path="BIGINT_COLUMN"/>
-		<obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
-		<obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
-		<obj-attribute name="charColumn" type="java.lang.String" db-attribute-path="CHAR_COLUMN"/>
-		<obj-attribute name="clobColumn" type="java.lang.String" db-attribute-path="CLOB_COLUMN"/>
-		<obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
-		<obj-attribute name="decimalColumn" type="java.math.BigDecimal" db-attribute-path="DECIMAL_COLUMN"/>
-		<obj-attribute name="doubleColumn" type="java.lang.Double" db-attribute-path="DOUBLE_COLUMN"/>
-		<obj-attribute name="floatColumn" type="java.lang.Float" db-attribute-path="FLOAT_COLUMN"/>
-		<obj-attribute name="integerColumn" type="java.lang.Integer" db-attribute-path="INTEGER_COLUMN"/>
-		<obj-attribute name="longvarcharColumn" type="java.lang.String" db-attribute-path="LONGVARCHAR_COLUMN"/>
-		<obj-attribute name="numericColumn" type="java.math.BigDecimal" db-attribute-path="NUMERIC_COLUMN"/>
-		<obj-attribute name="realColumn" type="java.lang.Float" db-attribute-path="REAL_COLUMN"/>
-		<obj-attribute name="smallintColumn" type="java.lang.Short" db-attribute-path="SMALLINT_COLUMN"/>
-		<obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
-		<obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
-		<obj-attribute name="tinyintColumn" type="java.lang.Byte" db-attribute-path="TINYINT_COLUMN"/>
-		<obj-attribute name="varcharColumn" type="java.lang.String" db-attribute-path="VARCHAR_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="ReturnTypesMap2" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap2" clientClassName="org.apache.cayenne.testdo.testmap.client.ReturnTypesMap2" dbEntityName="TYPES_MAPPING_TEST2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
-		<obj-attribute name="binaryColumn" type="byte[]" db-attribute-path="BINARY_COLUMN"/>
-		<obj-attribute name="blobColumn" type="byte[]" db-attribute-path="BLOB_COLUMN"/>
-		<obj-attribute name="longvarbinaryColumn" type="byte[]" db-attribute-path="LONGVARBINARY_COLUMN"/>
-		<obj-attribute name="varbinaryColumn" type="byte[]" db-attribute-path="VARBINARY_COLUMN"/>
-	</obj-entity>
-	<obj-entity name="SerializableEntity" className="org.apache.cayenne.testdo.misc_types.SerializableEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.SerializableEntity" dbEntityName="SERIALIZABLE_ENTITY">
-		<obj-attribute name="serializableField" type="org.apache.cayenne.MockSerializable" db-attribute-path="SERIALIZABLE_FIELD"/>
-	</obj-entity>
-	<obj-entity name="SmallintTestEntity" className="org.apache.cayenne.testdo.numeric_types.SmallintTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.SmallintTestEntity" dbEntityName="SMALLINT_TEST">
-		<obj-attribute name="smallintCol" type="java.lang.Short" db-attribute-path="SMALLINT_COL"/>
-	</obj-entity>
-	<obj-entity name="SubPainting" className="org.apache.cayenne.testdo.testmap.SubPainting" clientClassName="org.apache.cayenne.testdo.testmap.client.SubPainting" dbEntityName="PAINTING">
-		<obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
-	</obj-entity>
-	<obj-entity name="TinyintTestEntity" className="org.apache.cayenne.testdo.numeric_types.TinyintTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.TinyintTestEntity" dbEntityName="TINYINT_TEST">
-		<obj-attribute name="tinyintCol" type="java.lang.Byte" db-attribute-path="TINYINT_COL"/>
-	</obj-entity>
-	<obj-entity name="UuidTestEntity" className="org.apache.cayenne.testdo.uuid.UuidTestEntity" clientClassName="org.apache.cayenne.testdo.testmap.client.UuidTestEntity" dbEntityName="UUID_TEST">
-		<obj-attribute name="uuid" type="java.util.UUID" db-attribute-path="UUID"/>
-	</obj-entity>
-	<db-relationship name="artistGroupArray" source="ARTGROUP" target="ARTIST_GROUP" toMany="true">
-		<db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
-	</db-relationship>
-	<db-relationship name="toChildGroups" source="ARTGROUP" target="ARTGROUP" toMany="true">
-		<db-attribute-pair source="GROUP_ID" target="PARENT_GROUP_ID"/>
-	</db-relationship>
-	<db-relationship name="toParentGroup" source="ARTGROUP" target="ARTGROUP">
-		<db-attribute-pair source="PARENT_GROUP_ID" target="GROUP_ID"/>
-	</db-relationship>
-	<db-relationship name="artistExhibitArray" source="ARTIST" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="artistGroupArray" source="ARTIST" target="ARTIST_GROUP" toMany="true">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="paintingArray" source="ARTIST" target="PAINTING" toMany="true">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="toArtist" source="ARTIST_EXHIBIT" target="ARTIST">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="toExhibit" source="ARTIST_EXHIBIT" target="EXHIBIT">
-		<db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
-	</db-relationship>
-	<db-relationship name="toArtist" source="ARTIST_GROUP" target="ARTIST">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="toGroup" source="ARTIST_GROUP" target="ARTGROUP">
-		<db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
-	</db-relationship>
-	<db-relationship name="binaryPKDetails" source="BINARY_PK_TEST1" target="BINARY_PK_TEST2" toMany="true">
-		<db-attribute-pair source="BIN_ID" target="FK_ID"/>
-	</db-relationship>
-	<db-relationship name="toBinaryPKMaster" source="BINARY_PK_TEST2" target="BINARY_PK_TEST1">
-		<db-attribute-pair source="FK_ID" target="BIN_ID"/>
-	</db-relationship>
-	<db-relationship name="toCharPK" source="CHAR_FK_TEST" target="CHAR_PK_TEST">
-		<db-attribute-pair source="FK_COL" target="PK_COL"/>
-	</db-relationship>
-	<db-relationship name="charFKs" source="CHAR_PK_TEST" target="CHAR_FK_TEST" toMany="true">
-		<db-attribute-pair source="PK_COL" target="FK_COL"/>
-	</db-relationship>
-	<db-relationship name="clob" source="CLOB_TEST" target="CLOB_TEST_RELATION" toMany="true">
-		<db-attribute-pair source="CLOB_TEST_ID" target="ID_CLOB"/>
-	</db-relationship>
-	<db-relationship name="CLOB_REL" source="CLOB_TEST_RELATION" target="CLOB_TEST">
-		<db-attribute-pair source="ID_CLOB" target="CLOB_TEST_ID"/>
-	</db-relationship>
-	<db-relationship name="toCompoundPk" source="COMPOUND_FK_TEST" target="COMPOUND_PK_TEST">
-		<db-attribute-pair source="F_KEY1" target="KEY1"/>
-		<db-attribute-pair source="F_KEY2" target="KEY2"/>
-	</db-relationship>
-	<db-relationship name="compoundFkArray" source="COMPOUND_PK_TEST" target="COMPOUND_FK_TEST" toMany="true">
-		<db-attribute-pair source="KEY1" target="F_KEY1"/>
-		<db-attribute-pair source="KEY2" target="F_KEY2"/>
-	</db-relationship>
-	<db-relationship name="artistExhibitArray" source="EXHIBIT" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
-		<db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
-	</db-relationship>
-	<db-relationship name="toGallery" source="EXHIBIT" target="GALLERY">
-		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
-	</db-relationship>
-	<db-relationship name="exhibitArray" source="GALLERY" target="EXHIBIT" toMany="true">
-		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
-	</db-relationship>
-	<db-relationship name="paintingArray" source="GALLERY" target="PAINTING" toMany="true">
-		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
-	</db-relationship>
-	<db-relationship name="toMaster" source="GENERATED_COLUMN_COMP_KEY" target="GENERATED_COLUMN_COMP_M">
-		<db-attribute-pair source="PROPAGATED_PK" target="ID"/>
-	</db-relationship>
-	<db-relationship name="toDetail" source="GENERATED_COLUMN_COMP_M" target="GENERATED_COLUMN_COMP_KEY" toDependentPK="true" toMany="true">
-		<db-attribute-pair source="ID" target="PROPAGATED_PK"/>
-	</db-relationship>
-	<db-relationship name="toMaster" source="GENERATED_COLUMN_DEP" target="GENERATED_COLUMN_TEST">
-		<db-attribute-pair source="GENERATED_COLUMN_FK" target="GENERATED_COLUMN"/>
-	</db-relationship>
-	<db-relationship name="toDep" source="GENERATED_COLUMN_TEST" target="GENERATED_COLUMN_DEP" toDependentPK="true">
-		<db-attribute-pair source="GENERATED_COLUMN" target="GENERATED_COLUMN_FK"/>
-	</db-relationship>
-	<db-relationship name="join" source="GENERATED_F1" target="GENERATED_JOIN" toMany="true">
-		<db-attribute-pair source="ID" target="ID1"/>
-	</db-relationship>
-	<db-relationship name="join" source="GENERATED_F2" target="GENERATED_JOIN" toMany="true">
-		<db-attribute-pair source="ID" target="ID2"/>
-	</db-relationship>
-	<db-relationship name="f1" source="GENERATED_JOIN" target="GENERATED_F1">
-		<db-attribute-pair source="ID1" target="ID"/>
-	</db-relationship>
-	<db-relationship name="f2" source="GENERATED_JOIN" target="GENERATED_F2">
-		<db-attribute-pair source="ID2" target="ID"/>
-	</db-relationship>
-	<db-relationship name="toMeaningfulPK" source="MEANINGFUL_PK_DEP" target="MEANINGFUL_PK_TEST1">
-		<db-attribute-pair source="MASTER_PK" target="PK_ATTRIBUTE"/>
-	</db-relationship>
-	<db-relationship name="meaningfulPKDepArray" source="MEANINGFUL_PK_TEST1" target="MEANINGFUL_PK_DEP" toMany="true">
-		<db-attribute-pair source="PK_ATTRIBUTE" target="MASTER_PK"/>
-	</db-relationship>
-	<db-relationship name="details" source="MIXED_PERSISTENCE_STRATEGY" target="MIXED_PERSISTENCE_STRATEGY2" toMany="true">
-		<db-attribute-pair source="ID" target="MASTER_ID"/>
-	</db-relationship>
-	<db-relationship name="master" source="MIXED_PERSISTENCE_STRATEGY2" target="MIXED_PERSISTENCE_STRATEGY">
-		<db-attribute-pair source="MASTER_ID" target="ID"/>
-	</db-relationship>
-	<db-relationship name="toArtist" source="PAINTING" target="ARTIST">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="toGallery" source="PAINTING" target="GALLERY">
-		<db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
-	</db-relationship>
-	<db-relationship name="toPaintingInfo" source="PAINTING" target="PAINTING_INFO" toDependentPK="true">
-		<db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
-	</db-relationship>
-	<db-relationship name="toArtist" source="PAINTING1" target="ARTIST">
-		<db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
-	</db-relationship>
-	<db-relationship name="painting" source="PAINTING_INFO" target="PAINTING">
-		<db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
-	</db-relationship>
-	<obj-relationship name="artistArray" source="ArtGroup" target="Artist" deleteRule="Nullify" db-relationship-path="artistGroupArray.toArtist"/>
-	<obj-relationship name="childGroupsArray" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toChildGroups"/>
-	<obj-relationship name="toParentGroup" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toParentGroup"/>
-	<obj-relationship name="artistExhibitArray" source="Artist" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
-	<obj-relationship name="groupArray" source="Artist" target="ArtGroup" deleteRule="Cascade" db-relationship-path="artistGroupArray.toGroup"/>
-	<obj-relationship name="paintingArray" source="Artist" target="Painting" deleteRule="Cascade" db-relationship-path="paintingArray"/>
-	<obj-relationship name="toArtist" source="ArtistExhibit" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<obj-relationship name="toExhibit" source="ArtistExhibit" target="Exhibit" deleteRule="Nullify" db-relationship-path="toExhibit"/>
-	<obj-relationship name="binaryPKDetails" source="BinaryPKTest1" target="BinaryPKTest2" db-relationship-path="binaryPKDetails"/>
-	<obj-relationship name="toBinaryPKMaster" source="BinaryPKTest2" target="BinaryPKTest1" db-relationship-path="toBinaryPKMaster"/>
-	<obj-relationship name="toCharPK" source="CharFkTestEntity" target="CharPkTestEntity" db-relationship-path="toCharPK"/>
-	<obj-relationship name="charFKs" source="CharPkTestEntity" target="CharFkTestEntity" db-relationship-path="charFKs"/>
-	<obj-relationship name="clobValue" source="ClobTestEntity" target="ClobTestRelation" db-relationship-path="clob"/>
-	<obj-relationship name="clobId" source="ClobTestRelation" target="ClobTestEntity" db-relationship-path="CLOB_REL"/>
-	<obj-relationship name="toCompoundPk" source="CompoundFkTestEntity" target="CompoundPkTestEntity" db-relationship-path="toCompoundPk"/>
-	<obj-relationship name="toArtist" source="CompoundPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<obj-relationship name="toGallery" source="CompoundPainting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
-	<obj-relationship name="toPaintingInfo" source="CompoundPainting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
-	<obj-relationship name="compoundFkArray" source="CompoundPkTestEntity" target="CompoundFkTestEntity" db-relationship-path="compoundFkArray"/>
-	<obj-relationship name="artistExhibitArray" source="Exhibit" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
-	<obj-relationship name="toGallery" source="Exhibit" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
-	<obj-relationship name="exhibitArray" source="Gallery" target="Exhibit" deleteRule="Cascade" db-relationship-path="exhibitArray"/>
-	<obj-relationship name="paintingArray" source="Gallery" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
-	<obj-relationship name="toMaster" source="GeneratedColumnCompKey" target="GeneratedColumnCompMaster" db-relationship-path="toMaster"/>
-	<obj-relationship name="toDetail" source="GeneratedColumnCompMaster" target="GeneratedColumnCompKey" db-relationship-path="toDetail"/>
-	<obj-relationship name="toMaster" source="GeneratedColumnDep" target="GeneratedColumnTestEntity" db-relationship-path="toMaster"/>
-	<obj-relationship name="toDep" source="GeneratedColumnTestEntity" target="GeneratedColumnDep" db-relationship-path="toDep"/>
-	<obj-relationship name="f2" source="GeneratedF1" target="GeneratedF2" deleteRule="Nullify" db-relationship-path="join.f2"/>
-	<obj-relationship name="f1" source="GeneratedF2" target="GeneratedF1" deleteRule="Nullify" db-relationship-path="join.f1"/>
-	<obj-relationship name="toMeaningfulPK" source="MeaningfulPKDep" target="MeaningfulPKTest1" db-relationship-path="toMeaningfulPK"/>
-	<obj-relationship name="meaningfulPKDepArray" source="MeaningfulPKTest1" target="MeaningfulPKDep" db-relationship-path="meaningfulPKDepArray"/>
-	<obj-relationship name="details" source="MixedPersistenceStrategy" target="MixedPersistenceStrategy2" db-relationship-path="details"/>
-	<obj-relationship name="master" source="MixedPersistenceStrategy2" target="MixedPersistenceStrategy" db-relationship-path="master"/>
-	<obj-relationship name="toArtist" source="Painting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<obj-relationship name="toGallery" source="Painting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
-	<obj-relationship name="toPaintingInfo" source="Painting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
-	<obj-relationship name="toArtist" source="Painting1" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<obj-relationship name="painting" source="PaintingInfo" target="Painting" deleteRule="Nullify" db-relationship-path="painting"/>
-	<obj-relationship name="paintingArray" source="ROArtist" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
-	<obj-relationship name="toArtist" source="ROPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
-	<query name="EjbqlQueryTest" type="EJBQLQuery">
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<ejbql><![CDATA[select a from Artist a]]></ejbql>
-	</query>
-	<query name="NonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap-client">
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
-VALUES (512, 'No Painting Like This', 12.5)]]></sql>
-		<sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) VALUES (512, 'No Painting Like This', 12.5)]]></sql>
-	</query>
-	<query name="ObjectQuery" type="SelectQuery" root="obj-entity" root-name="Painting">
-		<qualifier><![CDATA[toArtist = $artist]]></qualifier>
-		<ordering><![CDATA[paintingTitle]]></ordering>
-	</query>
-	<query name="ParameterizedNonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap-client">
-		<sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
-VALUES (#bind($id), #bind($title), #bind($price))]]></sql>
-		<sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) values (#bind($id), #bind($title), #bind($price))]]></sql>
-	</query>
-	<query name="ParameterizedQueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
-		<qualifier><![CDATA[artistName like $name]]></qualifier>
-	</query>
-	<query name="ParameterizedQueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
-		<qualifier><![CDATA[artistName like $name]]></qualifier>
-	</query>
-	<query name="ProcedureQuery" type="ProcedureQuery" root="procedure" root-name="cayenne_tst_select_proc" result-entity="Artist"/>
-	<query name="QueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
-	</query>
-	<query name="QueryWithOrdering" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<ordering descending="true" ignore-case="true"><![CDATA[artistName]]></ordering>
-		<ordering><![CDATA[dateOfBirth]]></ordering>
-	</query>
-	<query name="QueryWithPrefetch" type="SelectQuery" root="obj-entity" root-name="Gallery">
-		<prefetch>paintingArray</prefetch>
-	</query>
-	<query name="QueryWithQualifier" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<qualifier><![CDATA[artistName = $param1]]></qualifier>
-	</query>
-	<query name="QueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
-		<property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
-	</query>
-	<query name="SelectDateTest" type="SQLTemplate" root="data-map" root-name="testmap-client">
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<sql><![CDATA[SELECT * FROM DATE_TEST]]></sql>
-	</query>
-	<query name="SelectReturnTypesMap1" type="SQLTemplate" root="data-map" root-name="testmap-client">
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST1]]></sql>
-	</query>
-	<query name="SelectReturnTypesMap2" type="SQLTemplate" root="data-map" root-name="testmap-client">
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST2]]></sql>
-	</query>
-	<query name="SelectTestLower" type="SQLTemplate" root="data-map" root-name="testmap-client">
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="LOWER"/>
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<sql><![CDATA[select * from ARTIST]]></sql>
-	</query>
-	<query name="SelectTestUpper" type="SQLTemplate" root="data-map" root-name="testmap-client">
-		<property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
-		<property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
-		<sql><![CDATA[select * from ARTIST]]></sql>
-	</query>
-</data-map>