This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/master by this push:
     new e77663894 CAY-2751 Simplify DataNode configuration  - drop password 
encoding  - simplify DataNode editor, remove tabs  - cleanup and rename 
DataSourceInfo  - deprecate JNDIDataSourceFactory
e77663894 is described below

commit e77663894e565699d337020563fd249129be0ac7
Author: Nikita Timofeev <stari...@gmail.com>
AuthorDate: Tue Jul 12 18:52:05 2022 +0300

    CAY-2751 Simplify DataNode configuration
     - drop password encoding
     - simplify DataNode editor, remove tabs
     - cleanup and rename DataSourceInfo
     - deprecate JNDIDataSourceFactory
---
 .../org/apache/cayenne/tools/DbImporterTask.java   |   4 +-
 .../configuration/DriverDataSourceFactory.java     |  12 +-
 .../reverse/dbimport/DbImportConfiguration.java    |   8 +-
 .../java/org/apache/cayenne/access/DataNode.java   |   1 -
 .../org/apache/cayenne/access/DbGenerator.java     |  35 +-
 .../cayenne/configuration/DataNodeDescriptor.java  |   9 +-
 .../configuration/DataSourceDescriptor.java        | 133 +++++++
 .../server/FixedJNDIDataSourceFactory.java         |   1 +
 .../server/JNDIDataSourceFactory.java              |   2 +
 .../configuration/server/ServerRuntimeBuilder.java |   1 +
 .../server/XMLPoolingDataSourceFactory.java        |  19 +-
 .../configuration/xml/DataNodeChildrenHandler.java |   6 +-
 .../xml/DataSourceChildrenHandler.java             |  76 +---
 .../org/apache/cayenne/conn/DataSourceInfo.java    | 423 ---------------------
 .../server/DefaultDataSourceFactoryLoaderTest.java |   6 +-
 .../server/ServerRuntimeBuilderIT.java             |   4 +-
 .../apache/cayenne/conn/DataSourceInfoTest.java    |  66 ----
 .../datasource/BasePoolingDataSourceIT.java        |   4 +-
 ...PoolingDataSource_FailingValidationQueryIT.java |   4 +-
 .../cayenne/unit/UnitDataSourceDescriptor.java     |  40 +-
 .../unit/di/server/ConnectionProperties.java       |  20 +-
 ...=> ServerCaseDataSourceDescriptorProvider.java} |  37 +-
 .../di/server/ServerCaseDataSourceFactory.java     |   6 +-
 .../di/server/ServerCaseDbAdapterProvider.java     |   8 +-
 .../cayenne/unit/di/server/ServerCaseModule.java   |  17 +-
 .../server/ServerCaseSharedDataSourceFactory.java  |   1 +
 .../unit/di/server/UnitDbAdapterProvider.java      |  17 +-
 .../cayenne/modeler/action/CreateNodeAction.java   |   6 +-
 .../modeler/action/ImportEOModelAction.java        |  15 +-
 .../modeler/editor/datanode/AdapterEditor.java     | 112 ------
 .../modeler/editor/datanode/AdapterView.java       |  56 ---
 .../editor/datanode/DBCP2DataSourceEditor.java     |  51 ---
 .../editor/datanode/DBCP2DataSourceView.java       |  54 ---
 .../modeler/editor/datanode/DataNodeEditor.java    |   2 -
 .../modeler/editor/datanode/DataSourceEditor.java  |   2 -
 .../editor/datanode/JDBCDataSourceEditor.java      |  18 +-
 .../editor/datanode/JNDIDataSourceView.java        |  56 ---
 .../editor/datanode/MainDataNodeEditor.java        |  30 +-
 .../modeler/editor/datanode/MainDataNodeView.java  |  23 +-
 .../editor/datanode/PasswordEncoderEditor.java     | 200 ----------
 .../editor/datanode/PasswordEncoderView.java       | 182 ---------
 .../cayenne/modeler/pref/DBConnectionInfo.java     |   6 +-
 .../modeler/action/CreateNodeActionTest.java       |  11 +-
 43 files changed, 299 insertions(+), 1485 deletions(-)

diff --git 
a/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java 
b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
index e331f2362..55cb506dc 100644
--- a/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
+++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
@@ -22,9 +22,9 @@ import javax.sql.DataSource;
 import java.io.File;
 
 import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.configuration.server.DataSourceFactory;
 import org.apache.cayenne.configuration.server.DbAdapterFactory;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbsync.DbSyncModule;
 import org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator;
@@ -184,7 +184,7 @@ public class DbImporterTask extends Task {
             error.append("The 'map' attribute must be set.\n");
         }
 
-        DataSourceInfo dataSourceInfo = config.getDataSourceInfo();
+        DataSourceDescriptor dataSourceInfo = config.getDataSourceInfo();
         if (dataSourceInfo.getJdbcDriver() == null) {
             error.append("The 'driver' attribute must be set.\n");
         }
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/DriverDataSourceFactory.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/DriverDataSourceFactory.java
index 23a2eb2d2..ed182d2d2 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/DriverDataSourceFactory.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/DriverDataSourceFactory.java
@@ -24,8 +24,8 @@ import java.sql.Driver;
 import javax.sql.DataSource;
 
 import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.configuration.server.DataSourceFactory;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.datasource.DriverDataSource;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Inject;
@@ -42,13 +42,13 @@ public class DriverDataSourceFactory implements 
DataSourceFactory {
        }
 
        public DataSource getDataSource(DataNodeDescriptor nodeDescriptor) 
throws Exception {
-               DataSourceInfo properties = 
nodeDescriptor.getDataSourceDescriptor();
-               if (properties == null) {
+               DataSourceDescriptor dataSourceDescriptor = 
nodeDescriptor.getDataSourceDescriptor();
+               if (dataSourceDescriptor == null) {
                        throw new IllegalArgumentException("'nodeDescriptor' 
contains no datasource descriptor");
                }
 
-               Driver driver = 
(Driver)objectFactory.getJavaClass(properties.getJdbcDriver()).getDeclaredConstructor().newInstance();
-               return new DriverDataSource(driver, 
properties.getDataSourceUrl(), properties.getUserName(),
-                               properties.getPassword());
+               Driver driver = 
(Driver)objectFactory.getJavaClass(dataSourceDescriptor.getJdbcDriver()).getDeclaredConstructor().newInstance();
+               return new DriverDataSource(driver, 
dataSourceDescriptor.getDataSourceUrl(), dataSourceDescriptor.getUserName(),
+                               dataSourceDescriptor.getPassword());
        }
 }
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
index cd7026bd5..f4e076faf 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
@@ -23,7 +23,7 @@ import java.util.regex.Pattern;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbsync.filter.NameFilter;
 import org.apache.cayenne.dbsync.filter.NamePatternMatcher;
@@ -48,7 +48,7 @@ public class DbImportConfiguration {
 
     private static final String DATA_MAP_LOCATION_SUFFIX = ".map.xml";
 
-    private final DataSourceInfo dataSourceInfo;
+    private final DataSourceDescriptor dataSourceInfo;
     private final DbLoaderConfiguration dbLoaderConfiguration;
     private File targetDataMap;
     private String defaultPackage;
@@ -65,7 +65,7 @@ public class DbImportConfiguration {
     private File cayenneProject;
 
     public DbImportConfiguration() {
-        this.dataSourceInfo = new DataSourceInfo();
+        this.dataSourceInfo = new DataSourceDescriptor();
         this.dbLoaderConfiguration = new DbLoaderConfiguration();
     }
 
@@ -288,7 +288,7 @@ public class DbImportConfiguration {
         return res.toString();
     }
 
-    public DataSourceInfo getDataSourceInfo() {
+    public DataSourceDescriptor getDataSourceInfo() {
         return dataSourceInfo;
     }
 
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataNode.java 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DataNode.java
index cb9f30831..1b5b8c10e 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataNode.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataNode.java
@@ -66,7 +66,6 @@ public class DataNode implements QueryEngine {
        protected String name;
        protected DataSource dataSource;
        protected DbAdapter adapter;
-       protected String dataSourceLocation;
        protected String dataSourceFactory;
        protected EntityResolver entityResolver;
        protected SchemaUpdateStrategy schemaUpdateStrategy;
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
index 5858b590b..022cc367b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
@@ -20,8 +20,6 @@
 package org.apache.cayenne.access;
 
 import org.apache.cayenne.ashwood.AshwoodEntitySorter;
-import org.apache.cayenne.conn.DataSourceInfo;
-import org.apache.cayenne.datasource.DriverDataSource;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.PkGenerator;
 import org.apache.cayenne.dba.TypesMapping;
@@ -40,7 +38,6 @@ import org.slf4j.LoggerFactory;
 
 import javax.sql.DataSource;
 import java.sql.Connection;
-import java.sql.Driver;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
@@ -58,7 +55,7 @@ import java.util.Map;
  */
 public class DbGenerator {
 
-       private static final Logger logObj = 
LoggerFactory.getLogger(DbGenerator.class);
+       private static final Logger LOGGER = 
LoggerFactory.getLogger(DbGenerator.class);
 
        protected DbAdapter adapter;
        protected DataMap map;
@@ -95,7 +92,7 @@ public class DbGenerator {
         * @since 3.1
         */
        public DbGenerator(DbAdapter adapter, DataMap map, JdbcEventLogger 
logger) {
-               this(adapter, map, logger, Collections.<DbEntity> emptyList());
+               this(adapter, map, logger, Collections.emptyList());
        }
 
        /**
@@ -240,26 +237,6 @@ public class DbGenerator {
                return list;
        }
 
-       /**
-        * Creates a temporary DataSource out of DataSourceInfo and invokes
-        * <code>public void runGenerator(DataSource ds)</code>.
-        */
-       public void runGenerator(DataSourceInfo dsi) throws Exception {
-               this.failures = null;
-
-               // do a pre-check. Maybe there is no need to run anything
-               // and therefore no need to create a connection
-               if (isEmpty(true)) {
-                       return;
-               }
-
-               Driver driver = (Driver) 
Class.forName(dsi.getJdbcDriver()).getDeclaredConstructor().newInstance();
-               DataSource dataSource = new DriverDataSource(driver, 
dsi.getDataSourceUrl(), dsi.getUserName(),
-                               dsi.getPassword());
-
-               runGenerator(dataSource);
-       }
-
        /**
         * Executes a set of commands to drop/create database objects. This is 
the
         * main worker method of DbGenerator. Command set is built based on
@@ -341,7 +318,7 @@ public class DbGenerator {
         * 
         * @since 1.1
         */
-       protected boolean safeExecute(Connection connection, String sql) throws 
SQLException {
+       protected boolean safeExecute(Connection connection, String sql) {
 
                try (Statement statement = connection.createStatement()) {
                        jdbcEventLogger.log(sql);
@@ -395,7 +372,7 @@ public class DbGenerator {
                                        DbRelationship reverse = 
rel.getReverseRelationship();
                                        if (reverse != null && 
!reverse.isToMany() && !reverse.isToPK()) {
 
-                                               String unique = 
getAdapter().createUniqueConstraint((DbEntity) rel.getSourceEntity(),
+                                               String unique = 
getAdapter().createUniqueConstraint(rel.getSourceEntity(),
                                                                
rel.getSourceAttributes());
                                                if (unique != null) {
                                                        list.add(unique);
@@ -501,7 +478,7 @@ public class DbGenerator {
 
                        // tables with no columns are not included
                        if (nextEntity.getAttributes().size() == 0) {
-                               logObj.info("Skipping entity with no 
attributes: " + nextEntity.getName());
+                               LOGGER.info("Skipping entity with no 
attributes: " + nextEntity.getName());
                                continue;
                        }
 
@@ -514,7 +491,7 @@ public class DbGenerator {
                        boolean invalidAttributes = false;
                        for (final DbAttribute attr : 
nextEntity.getAttributes()) {
                                if (attr.getType() == TypesMapping.NOT_DEFINED) 
{
-                                       logObj.info("Skipping entity, attribute 
type is undefined: " + nextEntity.getName() + "."
+                                       LOGGER.info("Skipping entity, attribute 
type is undefined: " + nextEntity.getName() + "."
                                                        + attr.getName());
                                        invalidAttributes = true;
                                        break;
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataNodeDescriptor.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataNodeDescriptor.java
index 236f459b7..07dbb58fb 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataNodeDescriptor.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataNodeDescriptor.java
@@ -20,7 +20,6 @@ package org.apache.cayenne.configuration;
 
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.resource.Resource;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.cayenne.util.XMLSerializable;
@@ -47,9 +46,7 @@ public class DataNodeDescriptor implements ConfigurationNode, 
XMLSerializable,
     protected String dataSourceFactoryType;
     protected String schemaUpdateStrategyType;
 
-    // TODO: andrus, 12.13.2009: replace funky DataSourceInfo with a cleaner 
new class
-    // (DataSourceDescriptor?)
-    protected DataSourceInfo dataSourceDescriptor;
+    protected DataSourceDescriptor dataSourceDescriptor;
 
     protected transient Resource configurationSource;
 
@@ -181,11 +178,11 @@ public class DataNodeDescriptor implements 
ConfigurationNode, XMLSerializable,
         this.schemaUpdateStrategyType = schemaUpdateStrategyClass;
     }
 
-    public DataSourceInfo getDataSourceDescriptor() {
+    public DataSourceDescriptor getDataSourceDescriptor() {
         return dataSourceDescriptor;
     }
 
-    public void setDataSourceDescriptor(DataSourceInfo dataSourceDescriptor) {
+    public void setDataSourceDescriptor(DataSourceDescriptor 
dataSourceDescriptor) {
         this.dataSourceDescriptor = dataSourceDescriptor;
     }
 
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataSourceDescriptor.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataSourceDescriptor.java
new file mode 100644
index 000000000..9e6ab1973
--- /dev/null
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataSourceDescriptor.java
@@ -0,0 +1,133 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://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.configuration;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import org.apache.cayenne.util.XMLEncoder;
+import org.apache.cayenne.util.XMLSerializable;
+
+/**
+ * Helper JavaBean class that holds DataSource information for the 
Cayenne-managed DataSource.
+ * @since 4.3
+ */
+public class DataSourceDescriptor implements Serializable, XMLSerializable {
+
+    protected String jdbcDriver;
+    protected String dataSourceUrl;
+    protected String userName;
+    protected String password;
+    protected int minConnections = 1;
+    protected int maxConnections = 1;
+
+    public String getJdbcDriver() {
+        return jdbcDriver;
+    }
+
+    public void setJdbcDriver(String jdbcDriver) {
+        this.jdbcDriver = jdbcDriver;
+    }
+
+    public String getDataSourceUrl() {
+        return dataSourceUrl;
+    }
+
+    public void setDataSourceUrl(String dataSourceUrl) {
+        this.dataSourceUrl = dataSourceUrl;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public int getMinConnections() {
+        return minConnections;
+    }
+
+    public void setMinConnections(int minConnections) {
+        this.minConnections = minConnections;
+    }
+
+    public int getMaxConnections() {
+        return maxConnections;
+    }
+
+    public void setMaxConnections(int maxConnections) {
+        this.maxConnections = maxConnections;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DataSourceDescriptor that = (DataSourceDescriptor) o;
+        return minConnections == that.minConnections
+                && maxConnections == that.maxConnections
+                && Objects.equals(jdbcDriver, that.jdbcDriver)
+                && Objects.equals(dataSourceUrl, that.dataSourceUrl)
+                && Objects.equals(userName, that.userName)
+                && Objects.equals(password, that.password);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(jdbcDriver, dataSourceUrl, userName, password, 
minConnections, maxConnections);
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor 
delegate) {
+        encoder.start("data-source")
+                .start("driver").attribute("value", jdbcDriver).end()
+                .start("url").attribute("value", dataSourceUrl).end()
+                .start("login")
+                    .attribute("userName", userName)
+                    .attribute("password", password).end()
+                .start("connectionPool")
+                    .attribute("min", minConnections)
+                    .attribute("max", maxConnections).end()
+                .end();
+    }
+
+    @Override
+    public String toString() {
+        return "[" + getClass().getName() + ":" +
+                "\n   driver: " + jdbcDriver +
+                "\n   url: " + dataSourceUrl +
+                "\n   user name: " + userName +
+                "\n   password: " + "**********" +
+                "\n   min. connections: " + minConnections +
+                "\n   max. connections: " + maxConnections +
+                "\n]";
+    }
+}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/FixedJNDIDataSourceFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/FixedJNDIDataSourceFactory.java
index 78b535df6..5b81472fd 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/FixedJNDIDataSourceFactory.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/FixedJNDIDataSourceFactory.java
@@ -23,6 +23,7 @@ import org.apache.cayenne.configuration.DataNodeDescriptor;
 /**
  * @since 4.0
  */
+@Deprecated
 class FixedJNDIDataSourceFactory extends JNDIDataSourceFactory {
 
     private String location;
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/JNDIDataSourceFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/JNDIDataSourceFactory.java
index 38716b600..fa1f47611 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/JNDIDataSourceFactory.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/JNDIDataSourceFactory.java
@@ -32,7 +32,9 @@ import org.slf4j.LoggerFactory;
  * Locates DataSource mapped via JNDI.
  * 
  * @since 3.1
+ * @deprecated since 4.3, unused by Cayenne
  */
+@Deprecated
 public class JNDIDataSourceFactory implements DataSourceFactory {
 
        private static final Logger LOGGER = 
LoggerFactory.getLogger(JNDIDataSourceFactory.class);
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilder.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilder.java
index f08655435..79556a6d2 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilder.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilder.java
@@ -100,6 +100,7 @@ public class ServerRuntimeBuilder {
      * DataNodes, and the DataSource is set with this method, the builder would
      * create a single default DataNode.
      */
+    @Deprecated
     public ServerRuntimeBuilder jndiDataSource(String location) {
         this.dataSourceFactory = new FixedJNDIDataSourceFactory(location);
         return this;
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/XMLPoolingDataSourceFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/XMLPoolingDataSourceFactory.java
index c17511cc1..b08d78cc7 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/XMLPoolingDataSourceFactory.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/XMLPoolingDataSourceFactory.java
@@ -25,8 +25,8 @@ import javax.sql.DataSource;
 import org.apache.cayenne.ConfigurationException;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.configuration.RuntimeProperties;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.datasource.DataSourceBuilder;
 import org.apache.cayenne.datasource.UnmanagedPoolingDataSource;
 import org.apache.cayenne.di.AdhocObjectFactory;
@@ -56,23 +56,26 @@ public class XMLPoolingDataSourceFactory implements 
DataSourceFactory {
        @Override
        public DataSource getDataSource(DataNodeDescriptor nodeDescriptor) 
throws Exception {
 
-               DataSourceInfo descriptor = 
nodeDescriptor.getDataSourceDescriptor();
-
+               DataSourceDescriptor descriptor = 
nodeDescriptor.getDataSourceDescriptor();
                if (descriptor == null) {
                        String message = "Null dataSourceDescriptor for 
nodeDescriptor '" + nodeDescriptor.getName() + "'";
                        logger.info(message);
                        throw new ConfigurationException(message);
                }
 
-               long maxQueueWaitTime = 
properties.getLong(Constants.JDBC_MAX_QUEUE_WAIT_TIME,
-                               
UnmanagedPoolingDataSource.MAX_QUEUE_WAIT_DEFAULT);
+               long maxQueueWaitTime = properties
+                               .getLong(Constants.JDBC_MAX_QUEUE_WAIT_TIME, 
UnmanagedPoolingDataSource.MAX_QUEUE_WAIT_DEFAULT);
 
-               Driver driver = 
(Driver)objectFactory.getJavaClass(descriptor.getJdbcDriver()).getDeclaredConstructor().newInstance();
+               Driver driver = 
(Driver)objectFactory.getJavaClass(descriptor.getJdbcDriver())
+                               .getDeclaredConstructor().newInstance();
 
-               return 
DataSourceBuilder.url(descriptor.getDataSourceUrl()).driver(driver).userName(descriptor.getUserName())
+               return DataSourceBuilder.url(descriptor.getDataSourceUrl())
+                               .driver(driver)
+                               .userName(descriptor.getUserName())
                                .password(descriptor.getPassword())
                                .pool(descriptor.getMinConnections(), 
descriptor.getMaxConnections())
-                               .maxQueueWaitTime(maxQueueWaitTime).build();
+                               .maxQueueWaitTime(maxQueueWaitTime)
+                               .build();
        }
 
 }
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java
index 116a30aa6..4a7f0b365 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java
@@ -20,7 +20,7 @@
 package org.apache.cayenne.configuration.xml;
 
 import org.apache.cayenne.configuration.DataNodeDescriptor;
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 
@@ -35,7 +35,7 @@ final class DataNodeChildrenHandler extends 
NamespaceAwareNestedTagHandler {
     private XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader;
     private DataNodeDescriptor nodeDescriptor;
 
-    private DataSourceInfo dataSourceDescriptor;
+    private DataSourceDescriptor dataSourceDescriptor;
 
     DataNodeChildrenHandler(XMLDataChannelDescriptorLoader 
xmlDataChannelDescriptorLoader, NamespaceAwareNestedTagHandler parentHandler, 
DataNodeDescriptor nodeDescriptor) {
         super(parentHandler);
@@ -62,7 +62,7 @@ final class DataNodeChildrenHandler extends 
NamespaceAwareNestedTagHandler {
     protected ContentHandler createChildTagHandler(String namespaceURI, String 
localName,
                                                    String name, Attributes 
attributes) {
         if (DATA_SOURCE_TAG.equals(localName)) {
-            dataSourceDescriptor = new DataSourceInfo();
+            dataSourceDescriptor = new DataSourceDescriptor();
             return new 
DataSourceChildrenHandler(xmlDataChannelDescriptorLoader, this, 
dataSourceDescriptor);
         }
 
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java
index a0bf91fdb..950b7fc8b 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java
@@ -19,13 +19,8 @@
 
 package org.apache.cayenne.configuration.xml;
 
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-
 import org.apache.cayenne.ConfigurationException;
-import org.apache.cayenne.configuration.PasswordEncoding;
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.xml.sax.Attributes;
@@ -44,11 +39,11 @@ class DataSourceChildrenHandler extends 
NamespaceAwareNestedTagHandler {
 
 
     private XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader;
-    private DataSourceInfo dataSourceDescriptor;
+    private DataSourceDescriptor dataSourceDescriptor;
 
     DataSourceChildrenHandler(XMLDataChannelDescriptorLoader 
xmlDataChannelDescriptorLoader,
                               DataNodeChildrenHandler parentHandler,
-                              DataSourceInfo dataSourceDescriptor) {
+                              DataSourceDescriptor dataSourceDescriptor) {
         super(parentHandler);
         this.xmlDataChannelDescriptorLoader = xmlDataChannelDescriptorLoader;
         this.dataSourceDescriptor = dataSourceDescriptor;
@@ -78,73 +73,10 @@ class DataSourceChildrenHandler extends 
NamespaceAwareNestedTagHandler {
     }
 
     void configureCredentials(Attributes attributes) {
-        String encoderClass = attributes.getValue("encoderClass");
-
-        String encoderKey = attributes.getValue("encoderKey");
-        if (encoderKey == null) {
-            encoderKey = attributes.getValue("encoderSalt");
-        }
-
         String password = attributes.getValue("password");
-        String passwordLocation = attributes.getValue("passwordLocation");
-        String passwordSource = attributes.getValue("passwordSource");
-        if (passwordSource == null) {
-            passwordSource = DataSourceInfo.PASSWORD_LOCATION_MODEL;
-        }
-
         String username = attributes.getValue("userName");
-
-        dataSourceDescriptor.setPasswordEncoderClass(encoderClass);
-        dataSourceDescriptor.setPasswordEncoderKey(encoderKey);
-        dataSourceDescriptor.setPasswordLocation(passwordLocation);
-        dataSourceDescriptor.setPasswordSource(passwordSource);
         dataSourceDescriptor.setUserName(username);
-
-        // Replace {} in passwordSource with encoderSalt -- useful for 
EXECUTABLE & URL options
-        if (encoderKey != null) {
-            passwordSource = passwordSource.replaceAll("\\{}", encoderKey);
-        }
-
-        String encoderType = dataSourceDescriptor.getPasswordEncoderClass();
-        PasswordEncoding passwordEncoder = null;
-        if (encoderType != null) {
-            passwordEncoder = 
xmlDataChannelDescriptorLoader.objectFactory.newInstance(PasswordEncoding.class,
 encoderType);
-        }
-
-        if (passwordLocation != null) {
-            switch (passwordLocation) {
-                case DataSourceInfo.PASSWORD_LOCATION_CLASSPATH:
-
-                    ClassLoader classLoader = 
Thread.currentThread().getContextClassLoader();
-                    URL url = classLoader.getResource(username);
-                    if (url != null) {
-                        password = 
XMLDataChannelDescriptorLoader.passwordFromURL(url);
-                    } else {
-                        logger.error("Could not find resource in CLASSPATH: " 
+ passwordSource);
-                    }
-                    break;
-                case DataSourceInfo.PASSWORD_LOCATION_URL:
-                    try {
-                        password = 
XMLDataChannelDescriptorLoader.passwordFromURL(new URL(passwordSource));
-                    } catch (MalformedURLException exception) {
-                        logger.warn(exception.getMessage(), exception);
-                    }
-                    break;
-                case DataSourceInfo.PASSWORD_LOCATION_EXECUTABLE:
-                    try {
-                        Process process = 
Runtime.getRuntime().exec(passwordSource);
-                        password = 
XMLDataChannelDescriptorLoader.passwordFromInputStream(process.getInputStream());
-                        process.waitFor();
-                    } catch (IOException | InterruptedException exception) {
-                        logger.warn(exception.getMessage(), exception);
-                    }
-                    break;
-            }
-        }
-
-        if (password != null && passwordEncoder != null) {
-            
dataSourceDescriptor.setPassword(passwordEncoder.decodePassword(password, 
encoderKey));
-        }
+        dataSourceDescriptor.setPassword(password);
     }
 
     void configureConnectionPool(Attributes attributes) {
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/conn/DataSourceInfo.java 
b/cayenne-server/src/main/java/org/apache/cayenne/conn/DataSourceInfo.java
deleted file mode 100644
index 05b65e1eb..000000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/conn/DataSourceInfo.java
+++ /dev/null
@@ -1,423 +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
- *
- *    https://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.conn;
-
-import java.io.Serializable;
-import java.util.Objects;
-
-import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
-import org.apache.cayenne.configuration.PasswordEncoding;
-import org.apache.cayenne.configuration.PlainTextPasswordEncoder;
-import org.apache.cayenne.di.DIRuntimeException;
-import org.apache.cayenne.util.Util;
-import org.apache.cayenne.util.XMLEncoder;
-import org.apache.cayenne.util.XMLSerializable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Helper JavaBean class that holds DataSource login information.
- */
-public class DataSourceInfo implements Cloneable, Serializable, 
XMLSerializable {
-
-       private static final long serialVersionUID = 3748394113864532902L;
-
-       private static final Logger logger = 
LoggerFactory.getLogger(DataSourceInfo.class);
-
-       public static final String PASSWORD_LOCATION_CLASSPATH = "classpath";
-       public static final String PASSWORD_LOCATION_EXECUTABLE = "executable";
-       public static final String PASSWORD_LOCATION_MODEL = "model";
-       public static final String PASSWORD_LOCATION_URL = "url";
-
-       protected String userName;
-       protected String password;
-       protected String jdbcDriver;
-       protected String dataSourceUrl;
-       protected String adapterClassName;
-       protected int minConnections = 1;
-       protected int maxConnections = 1;
-       protected String passwordEncoderClass = 
PlainTextPasswordEncoder.class.getName();
-       protected String passwordEncoderKey = "";
-       protected String passwordLocation = PASSWORD_LOCATION_MODEL;
-       protected String passwordSourceExecutable = "";
-       protected String passwordSourceFilename = "";
-       protected final String passwordSourceModel = "Not Applicable";
-       protected String passwordSourceUrl = "";
-
-       @Override
-       public boolean equals(Object obj) {
-               
-               if (obj == this) {
-                       return true;
-               }
-
-               if (obj == null) {
-                       return false;
-               }
-
-               if (obj.getClass() != this.getClass()) {
-                       return false;
-               }
-
-               DataSourceInfo dsi = (DataSourceInfo) obj;
-
-               if (!Util.nullSafeEquals(this.userName, dsi.userName)) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.password, dsi.password)) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.jdbcDriver, dsi.jdbcDriver)) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.dataSourceUrl, 
dsi.dataSourceUrl)) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.adapterClassName, 
dsi.adapterClassName)) {
-                       return false;
-               }
-
-               if (this.minConnections != dsi.minConnections) {
-                       return false;
-               }
-
-               if (this.maxConnections != dsi.maxConnections) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.passwordEncoderClass, 
dsi.passwordEncoderClass)) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.passwordEncoderKey, 
dsi.passwordEncoderKey)) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.passwordSourceFilename, 
dsi.passwordSourceFilename)) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.passwordSourceModel, 
dsi.passwordSourceModel)) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.passwordSourceUrl, 
dsi.passwordSourceUrl)) {
-                       return false;
-               }
-
-               if (!Util.nullSafeEquals(this.passwordLocation, 
dsi.passwordLocation)) {
-                       return false;
-               }
-
-               return true;
-       }
-
-       @Override
-       public int hashCode() {
-               return Objects.hash(userName, password, jdbcDriver,
-                               dataSourceUrl, adapterClassName, minConnections,
-                               maxConnections, passwordEncoderClass, 
passwordEncoderKey,
-                               passwordLocation, passwordSourceFilename, 
passwordSourceModel,
-                               passwordSourceUrl);
-       }
-
-       /**
-        * @since 3.1
-        */
-       @Override
-       public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor 
delegate) {
-               encoder.start("data-source");
-
-               encoder.start("driver").attribute("value", jdbcDriver).end();
-               encoder.start("url").attribute("value", dataSourceUrl).end();
-
-               encoder.start("connectionPool")
-                               .attribute("min", minConnections)
-                               .attribute("max", 
String.valueOf(maxConnections))
-                               .end();
-
-               encoder.start("login").attribute("userName", userName);
-
-               if 
(DataSourceInfo.PASSWORD_LOCATION_MODEL.equals(passwordLocation)) {
-                       PasswordEncoding passwordEncoder = getPasswordEncoder();
-                       if (passwordEncoder != null) {
-                               String passwordEncoded = 
passwordEncoder.encodePassword(password, passwordEncoderKey);
-                               encoder.attribute("password", passwordEncoded);
-                       }
-               }
-
-               if 
(!PlainTextPasswordEncoder.class.getName().equals(passwordEncoderClass)) {
-                       encoder.attribute("encoderClass", passwordEncoderClass);
-               }
-
-               encoder.attribute("encoderKey", passwordEncoderKey);
-
-               if 
(!DataSourceInfo.PASSWORD_LOCATION_MODEL.equals(passwordLocation)) {
-                       encoder.attribute("passwordLocation", passwordLocation);
-               }
-
-               // TODO: this is very not nice... we need to clean up the whole
-               // DataSourceInfo to avoid returning arbitrary labels...
-               String passwordSource = getPasswordSource();
-               if (!"Not Applicable".equals(passwordSource)) {
-                       encoder.attribute("passwordSource", passwordSource);
-               }
-
-               encoder.end().end();
-       }
-
-       public DataSourceInfo cloneInfo() {
-               try {
-                       return (DataSourceInfo) super.clone();
-               } catch (CloneNotSupportedException ex) {
-                       throw new RuntimeException("Cloning error", ex);
-               }
-       }
-
-       public String getAdapterClassName() {
-               return adapterClassName;
-       }
-
-       public void setAdapterClassName(String adapterClassName) {
-               this.adapterClassName = adapterClassName;
-       }
-
-       public void setMinConnections(int minConnections) {
-               this.minConnections = minConnections;
-       }
-
-       public int getMinConnections() {
-               return minConnections;
-       }
-
-       public void setMaxConnections(int maxConnections) {
-               this.maxConnections = maxConnections;
-       }
-
-       public int getMaxConnections() {
-               return maxConnections;
-       }
-
-       public void setUserName(String userName) {
-               this.userName = userName;
-       }
-
-       public String getUserName() {
-               return userName;
-       }
-
-       public void setPassword(String password) {
-               this.password = password;
-       }
-
-       public String getPassword() {
-               return password;
-       }
-
-       public void setJdbcDriver(String jdbcDriver) {
-               this.jdbcDriver = jdbcDriver;
-       }
-
-       public String getJdbcDriver() {
-               return jdbcDriver;
-       }
-
-       public void setDataSourceUrl(String dataSourceUrl) {
-               this.dataSourceUrl = dataSourceUrl;
-       }
-
-       public String getDataSourceUrl() {
-               return dataSourceUrl;
-       }
-
-       /**
-        * @deprecated since 4.0 as class loading should not happen here.
-        */
-       @Deprecated
-       public PasswordEncoding getPasswordEncoder() {
-               try {
-                       return (PasswordEncoding) 
Util.getJavaClass(getPasswordEncoderClass()).newInstance();
-               } catch (InstantiationException | IllegalAccessException | 
ClassNotFoundException | DIRuntimeException e) {
-                       ; // Swallow it -- no need to throw/etc.
-               }
-
-               logger.error("Failed to obtain specified Password Encoder '" + 
getPasswordEncoderClass() + "'");
-               return null;
-       }
-
-       /**
-        * @return the passwordEncoderClass
-        */
-       public String getPasswordEncoderClass() {
-               return passwordEncoderClass;
-       }
-
-       /**
-        * @param passwordEncoderClass
-        *            the passwordEncoderClass to set
-        */
-       public void setPasswordEncoderClass(String passwordEncoderClass) {
-               if (passwordEncoderClass == null) {
-                       this.passwordEncoderClass = 
PasswordEncoding.standardEncoders[0];
-               } else {
-                       this.passwordEncoderClass = passwordEncoderClass;
-               }
-       }
-
-       /**
-        * @return the passwordEncoderKey
-        */
-       public String getPasswordEncoderKey() {
-               return passwordEncoderKey;
-       }
-
-       /**
-        * @param passwordEncoderKey
-        *            the passwordEncoderKey to set
-        */
-       public void setPasswordEncoderKey(String passwordEncoderKey) {
-               this.passwordEncoderKey = passwordEncoderKey;
-       }
-
-       /**
-        * @return the passwordLocationFilename
-        */
-       public String getPasswordSourceFilename() {
-               return passwordSourceFilename;
-       }
-
-       /**
-        * @param passwordSourceFilename
-        *            the passwordSourceFilename to set
-        */
-       public void setPasswordSourceFilename(String passwordSourceFilename) {
-               this.passwordSourceFilename = passwordSourceFilename;
-       }
-
-       /**
-        * @return the passwordLocationModel
-        */
-       public String getPasswordSourceModel() {
-               return passwordSourceModel;
-       }
-
-       /**
-        * @return the passwordLocationUrl
-        */
-       public String getPasswordSourceUrl() {
-               return passwordSourceUrl;
-       }
-
-       /**
-        * @param passwordSourceUrl
-        *            the passwordSourceUrl to set
-        */
-       public void setPasswordSourceUrl(String passwordSourceUrl) {
-               this.passwordSourceUrl = passwordSourceUrl;
-       }
-
-       /**
-        * @return the passwordLocationExecutable
-        */
-       public String getPasswordSourceExecutable() {
-               return passwordSourceExecutable;
-       }
-
-       /**
-        * @param passwordSourceExecutable
-        *            the passwordSourceExecutable to set
-        */
-       public void setPasswordSourceExecutable(String 
passwordSourceExecutable) {
-               this.passwordSourceExecutable = passwordSourceExecutable;
-       }
-
-       public String getPasswordSource() {
-               if (getPasswordLocation().equals(PASSWORD_LOCATION_CLASSPATH)) {
-                       return getPasswordSourceFilename();
-               } else if 
(getPasswordLocation().equals(PASSWORD_LOCATION_EXECUTABLE)) {
-                       return getPasswordSourceExecutable();
-               } else if 
(getPasswordLocation().equals(PASSWORD_LOCATION_MODEL)) {
-                       return getPasswordSourceModel();
-               } else if (getPasswordLocation().equals(PASSWORD_LOCATION_URL)) 
{
-                       return getPasswordSourceUrl();
-               }
-
-               throw new RuntimeException("Invalid password source detected");
-       }
-
-       public void setPasswordSource(String passwordSource) {
-               // The location for the model is omitted since it cannot change
-               if (getPasswordLocation().equals(PASSWORD_LOCATION_CLASSPATH)) {
-                       setPasswordSourceFilename(passwordSource);
-               } else if 
(getPasswordLocation().equals(PASSWORD_LOCATION_EXECUTABLE)) {
-                       setPasswordSourceExecutable(passwordSource);
-               } else if (getPasswordLocation().equals(PASSWORD_LOCATION_URL)) 
{
-                       setPasswordSourceUrl(passwordSource);
-               }
-       }
-
-       /**
-        * @return the passwordLocation
-        */
-       public String getPasswordLocation() {
-               return passwordLocation;
-       }
-
-       /**
-        * @param passwordLocation
-        *            the passwordLocation to set
-        */
-       public void setPasswordLocation(String passwordLocation) {
-               if (passwordLocation == null) {
-                       this.passwordLocation = 
DataSourceInfo.PASSWORD_LOCATION_MODEL;
-               } else {
-                       this.passwordLocation = passwordLocation;
-               }
-       }
-
-       @Override
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-               
buffer.append("[").append(getClass().getName()).append(":").append("\n   user 
name: ").append(userName)
-                               .append("\n   password: ");
-
-               buffer.append("**********");
-               buffer.append("\n   driver: ").append(jdbcDriver).append("\n   
db adapter class: ").append(adapterClassName)
-                               .append("\n   url: 
").append(dataSourceUrl).append("\n   min. connections: 
").append(minConnections)
-                               .append("\n   max. connections: 
").append(maxConnections);
-
-               if 
(!PlainTextPasswordEncoder.class.getName().equals(passwordEncoderClass)) {
-                       buffer.append("\n   encoder class: 
").append(passwordEncoderClass).append("\n   encoder key: ")
-                                       .append(passwordEncoderKey);
-               }
-
-               if (!PASSWORD_LOCATION_MODEL.equals(passwordLocation)) {
-                       buffer.append("\n   password location: 
").append(passwordLocation).append("\n   password source: ")
-                                       .append(getPasswordSource());
-               }
-
-               buffer.append("\n]");
-               return buffer.toString();
-       }
-}
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDataSourceFactoryLoaderTest.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDataSourceFactoryLoaderTest.java
index 3f718668f..3bc339401 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDataSourceFactoryLoaderTest.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDataSourceFactoryLoaderTest.java
@@ -21,9 +21,9 @@ package org.apache.cayenne.configuration.server;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.configuration.RuntimeProperties;
 import org.apache.cayenne.configuration.mock.MockDataSourceFactory1;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.ClassLoaderManager;
 import org.apache.cayenne.di.DIBootstrap;
@@ -65,11 +65,11 @@ public class DefaultDataSourceFactoryLoaderTest {
     }
 
     @Test
-    public void testGetDataSourceFactory_Implicit() throws Exception {
+    public void testGetDataSourceFactory_Implicit() {
 
         DataNodeDescriptor nodeDescriptor = new DataNodeDescriptor();
         nodeDescriptor.setName("node1");
-        nodeDescriptor.setDataSourceDescriptor(new DataSourceInfo());
+        nodeDescriptor.setDataSourceDescriptor(new DataSourceDescriptor());
 
         DelegatingDataSourceFactory factoryLoader = new 
DelegatingDataSourceFactory();
         injector.injectMembers(factoryLoader);
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilderIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilderIT.java
index 8eb4a62b0..648a92085 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilderIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilderIT.java
@@ -29,7 +29,7 @@ import javax.sql.DataSource;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.access.DataNode;
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.query.SQLSelect;
@@ -53,7 +53,7 @@ public class ServerRuntimeBuilderIT extends ServerCase {
        private ServerRuntime runtime;
 
        @Inject
-       private DataSourceInfo dsi;
+       private DataSourceDescriptor dsi;
 
        private ServerRuntime localRuntime;
        private DataSource dataSource;
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/conn/DataSourceInfoTest.java 
b/cayenne-server/src/test/java/org/apache/cayenne/conn/DataSourceInfoTest.java
deleted file mode 100644
index e74040356..000000000
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/conn/DataSourceInfoTest.java
+++ /dev/null
@@ -1,66 +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
- *
- *    https://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.conn;
-
-import org.apache.cayenne.util.Util;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-public class DataSourceInfoTest {
-
-    private DataSourceInfo dsi;
-
-    @Before
-    public void setUp() throws Exception {
-        dsi = new DataSourceInfo();
-        dsi.setUserName("a");
-        dsi.setPassword("b");
-        dsi.setMinConnections(1);
-        dsi.setMaxConnections(2);
-        dsi.setJdbcDriver("b");
-        dsi.setDataSourceUrl("c");
-        dsi.setAdapterClassName("d");
-    }
-
-    @Test
-    public void testDefaultValues() throws java.lang.Exception {
-        DataSourceInfo localDsi = new DataSourceInfo();
-        assertEquals(1, localDsi.getMinConnections());
-        assertTrue(localDsi.getMinConnections() <= 
localDsi.getMaxConnections());
-    }
-
-    @Test
-    public void testClone() throws java.lang.Exception {
-        DataSourceInfo dsiClone = dsi.cloneInfo();
-        assertEquals(dsi, dsiClone);
-        assertTrue(dsi != dsiClone);
-    }
-
-    @Test
-    public void testSerialize() throws java.lang.Exception {
-        DataSourceInfo dsiUnserialized = Util.cloneViaSerialization(dsi);
-        assertEquals(dsi, dsiUnserialized);
-        assertTrue(dsi != dsiUnserialized);
-    }
-
-}
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/BasePoolingDataSourceIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/BasePoolingDataSourceIT.java
index 0100f77e7..25be1e62e 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/BasePoolingDataSourceIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/BasePoolingDataSourceIT.java
@@ -21,7 +21,7 @@ package org.apache.cayenne.datasource;
 import java.sql.Driver;
 import java.sql.SQLException;
 
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.unit.di.server.CayenneProjects;
@@ -36,7 +36,7 @@ public class BasePoolingDataSourceIT extends ServerCase {
        protected static final long QUEUE_WAIT_TIME = 1000L;
 
        @Inject
-       private DataSourceInfo dataSourceInfo;
+       private DataSourceDescriptor dataSourceInfo;
 
        @Inject
        private AdhocObjectFactory objectFactory;
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSource_FailingValidationQueryIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSource_FailingValidationQueryIT.java
index e0749c1fb..b4de09fb9 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSource_FailingValidationQueryIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSource_FailingValidationQueryIT.java
@@ -21,7 +21,7 @@ package org.apache.cayenne.datasource;
 import java.sql.Driver;
 
 import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.unit.di.server.CayenneProjects;
@@ -33,7 +33,7 @@ import org.junit.Test;
 public class PoolingDataSource_FailingValidationQueryIT extends ServerCase {
 
        @Inject
-       private DataSourceInfo dataSourceInfo;
+       private DataSourceDescriptor dataSourceInfo;
 
        @Inject
        private AdhocObjectFactory objectFactory;
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JNDIDataSourceEditor.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/UnitDataSourceDescriptor.java
similarity index 50%
rename from 
modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JNDIDataSourceEditor.java
rename to 
cayenne-server/src/test/java/org/apache/cayenne/unit/UnitDataSourceDescriptor.java
index 1b6c5c0be..9f2e85cb9 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JNDIDataSourceEditor.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/UnitDataSourceDescriptor.java
@@ -17,36 +17,34 @@
  *  under the License.
  ****************************************************************/
 
-package org.apache.cayenne.modeler.editor.datanode;
+package org.apache.cayenne.unit;
 
-import java.awt.Component;
-
-import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.swing.BindingBuilder;
-import org.apache.cayenne.swing.BindingDelegate;
-import org.apache.cayenne.swing.ObjectBinding;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 
 /**
+ * Extension of the {@link DataSourceDescriptor} for tests that adds 
adapterClassName field to it.
  */
-public class JNDIDataSourceEditor extends DataSourceEditor {
+public class UnitDataSourceDescriptor extends DataSourceDescriptor {
 
-    protected JNDIDataSourceView view;
+    protected String adapterClassName;
 
-    public JNDIDataSourceEditor(ProjectController parent,
-            BindingDelegate nodeChangeProcessor) {
-        super(parent, nodeChangeProcessor);
+    public String getAdapterClassName() {
+        return adapterClassName;
     }
 
-    public Component getView() {
-        return view;
+    public void setAdapterClassName(String adapterClassName) {
+        this.adapterClassName = adapterClassName;
     }
 
-    protected void prepareBindings(BindingBuilder builder) {
-        this.view = new JNDIDataSourceView();
-
-        fieldAdapters = new ObjectBinding[1];
-        fieldAdapters[0] = builder.bindToTextField(
-                view.getJndiPath(),
-                "node.parameters");
+    public UnitDataSourceDescriptor copy() {
+        UnitDataSourceDescriptor copy = new UnitDataSourceDescriptor();
+        copy.setDataSourceUrl(getDataSourceUrl());
+        copy.setJdbcDriver(getJdbcDriver());
+        copy.setUserName(getUserName());
+        copy.setPassword(getPassword());
+        copy.setAdapterClassName(getAdapterClassName());
+        copy.setMinConnections(getMinConnections());
+        copy.setMaxConnections(getMaxConnections());
+        return copy;
     }
 }
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ConnectionProperties.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ConnectionProperties.java
index e974b459e..b8d8796b3 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ConnectionProperties.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ConnectionProperties.java
@@ -19,7 +19,7 @@
 
 package org.apache.cayenne.unit.di.server;
 
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.unit.UnitDataSourceDescriptor;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -45,15 +45,15 @@ class ConnectionProperties {
        private static final String URL_KEY = "jdbc.url";
        private static final String DRIVER_KEY = "jdbc.driver";
 
-       private Map<String, DataSourceInfo> connectionInfos;
+       private Map<String, UnitDataSourceDescriptor> connectionDescriptors;
 
        /**
         * Constructor for ConnectionProperties.
         */
        ConnectionProperties(Map<String, String> props) {
-               connectionInfos = new HashMap<>();
+               connectionDescriptors = new HashMap<>();
                for (String name : extractNames(props)) {
-                       DataSourceInfo dsi = buildDataSourceInfo(
+                       UnitDataSourceDescriptor dsi = 
buildDataSourceDescriptor(
                                        props.entrySet().stream()
                                                        .filter(e -> 
e.getKey().startsWith(name + '.'))
                                                        
.collect(Collectors.toMap(
@@ -64,27 +64,27 @@ class ConnectionProperties {
                                                                        
Map.Entry::getValue
                                                        ))
                        );
-                       connectionInfos.put(name, dsi);
+                       connectionDescriptors.put(name, dsi);
                }
        }
 
        int size() {
-               return connectionInfos.size();
+               return connectionDescriptors.size();
        }
 
        /**
         * Returns DataSourceInfo object for a symbolic name. If name does not 
match
         * an existing object, returns null.
         */
-       DataSourceInfo getConnection(String name) {
-               return connectionInfos.get(name);
+       UnitDataSourceDescriptor getConnection(String name) {
+               return connectionDescriptors.get(name);
        }
 
        /**
         * Creates a DataSourceInfo object from a set of properties.
         */
-       private DataSourceInfo buildDataSourceInfo(Map<String, String> props) {
-               DataSourceInfo dsi = new DataSourceInfo();
+       private UnitDataSourceDescriptor buildDataSourceDescriptor(Map<String, 
String> props) {
+               UnitDataSourceDescriptor dsi = new UnitDataSourceDescriptor();
 
                String adapter = props.get(ADAPTER_KEY);
 
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceInfoProvider.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceDescriptorProvider.java
similarity index 85%
rename from 
cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceInfoProvider.java
rename to 
cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceDescriptorProvider.java
index 9c8186c64..d887703de 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceInfoProvider.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceDescriptorProvider.java
@@ -19,13 +19,13 @@
 package org.apache.cayenne.unit.di.server;
 
 import org.apache.cayenne.ConfigurationException;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dba.derby.DerbyAdapter;
 import org.apache.cayenne.dba.h2.H2Adapter;
 import org.apache.cayenne.dba.hsqldb.HSQLDBAdapter;
 import org.apache.cayenne.dba.sqlite.SQLiteAdapter;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.Provider;
+import org.apache.cayenne.unit.UnitDataSourceDescriptor;
 import org.apache.cayenne.unit.testcontainers.TestContainerProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,26 +38,25 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 
-public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo> {
+public class ServerCaseDataSourceDescriptorProvider implements 
Provider<UnitDataSourceDescriptor> {
 
-    private static Logger logger = 
LoggerFactory.getLogger(ServerCaseDataSourceInfoProvider.class);
+    private static final Logger logger = 
LoggerFactory.getLogger(ServerCaseDataSourceDescriptorProvider.class);
 
     private static final String PROPERTIES_FILE = "connection.properties";
     private static final String CONNECTION_NAME_KEY = "cayenneTestConnection";
     private static final String CONNECTION_DB_VERSION = "cayenneTestDbVersion";
-
     private static final String ADAPTER_KEY_MAVEN = "cayenneAdapter";
     private static final String USER_NAME_KEY_MAVEN = "cayenneJdbcUsername";
     private static final String PASSWORD_KEY_MAVEN = "cayenneJdbcPassword";
     private static final String URL_KEY_MAVEN = "cayenneJdbcUrl";
     private static final String DRIVER_KEY_MAVEN = "cayenneJdbcDriver";
 
-    private Map<String, DataSourceInfo> inMemoryDataSources;
+    private Map<String, UnitDataSourceDescriptor> inMemoryDataSources;
     private ConnectionProperties connectionProperties;
 
     private final Map<String, TestContainerProvider> testContainerProviders;
 
-    public ServerCaseDataSourceInfoProvider(@Inject Map<String, 
TestContainerProvider> testContainerProviders)
+    public ServerCaseDataSourceDescriptorProvider(@Inject Map<String, 
TestContainerProvider> testContainerProviders)
             throws IOException {
 
         this.testContainerProviders = testContainerProviders;
@@ -77,7 +76,7 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
 
         // preload default in-memory DataSources. Will use them as defaults if
         // nothing is configured in ~/.cayenne/connection.properties
-        DataSourceInfo hsqldb = new DataSourceInfo();
+        UnitDataSourceDescriptor hsqldb = new UnitDataSourceDescriptor();
         hsqldb.setAdapterClassName(HSQLDBAdapter.class.getName());
         hsqldb.setUserName("sa");
         hsqldb.setPassword("");
@@ -87,7 +86,7 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
         hsqldb.setMaxConnections(ConnectionProperties.MAX_CONNECTIONS);
         inMemoryDataSources.put("hsql", hsqldb);
 
-        DataSourceInfo h2 = new DataSourceInfo();
+        UnitDataSourceDescriptor h2 = new UnitDataSourceDescriptor();
         h2.setAdapterClassName(H2Adapter.class.getName());
         h2.setUserName("sa");
         h2.setPassword("");
@@ -97,7 +96,7 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
         h2.setMaxConnections(ConnectionProperties.MAX_CONNECTIONS);
         inMemoryDataSources.put("h2", h2);
 
-        DataSourceInfo derby = new DataSourceInfo();
+        UnitDataSourceDescriptor derby = new UnitDataSourceDescriptor();
         derby.setAdapterClassName(DerbyAdapter.class.getName());
         derby.setUserName("sa");
         derby.setPassword("");
@@ -107,7 +106,7 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
         derby.setMaxConnections(ConnectionProperties.MAX_CONNECTIONS);
         inMemoryDataSources.put("derby", derby);
 
-        DataSourceInfo sqlite = new DataSourceInfo();
+        UnitDataSourceDescriptor sqlite = new UnitDataSourceDescriptor();
         sqlite.setAdapterClassName(SQLiteAdapter.class.getName());
         sqlite.setUserName("sa");
         sqlite.setPassword("");
@@ -119,7 +118,7 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
     }
 
     @Override
-    public DataSourceInfo get() throws ConfigurationException {
+    public UnitDataSourceDescriptor get() throws ConfigurationException {
 
         String connectionKey = property(CONNECTION_NAME_KEY);
         if (connectionKey == null) {
@@ -127,7 +126,7 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
         }
 
         logger.info("Connection key: " + connectionKey);
-        DataSourceInfo connectionInfo = 
connectionProperties.getConnection(connectionKey);
+        UnitDataSourceDescriptor connectionInfo = 
connectionProperties.getConnection(connectionKey);
 
         // attempt default if invalid key is specified
         if (connectionInfo == null) {
@@ -148,7 +147,7 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
         return connectionInfo;
     }
 
-    private DataSourceInfo checkTestContainersDataSource(String connectionKey) 
{
+    private UnitDataSourceDescriptor checkTestContainersDataSource(String 
connectionKey) {
         // special case for the testcontainers profile
         if (!connectionKey.endsWith("-tc")) {
             return null;
@@ -164,7 +163,7 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
         String version = property(CONNECTION_DB_VERSION);
         JdbcDatabaseContainer<?> container = 
testContainerProvider.startContainer(version);
 
-        DataSourceInfo sourceInfo = new DataSourceInfo();
+        UnitDataSourceDescriptor sourceInfo = new UnitDataSourceDescriptor();
         
sourceInfo.setAdapterClassName(testContainerProvider.getAdapterClass().getName());
         sourceInfo.setUserName(container.getUsername());
         sourceInfo.setPassword(container.getPassword());
@@ -184,12 +183,16 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
         return new File(homeDir, ".cayenne");
     }
 
-    private DataSourceInfo applyOverrides(DataSourceInfo connectionInfo) {
+    private UnitDataSourceDescriptor applyOverrides(UnitDataSourceDescriptor 
connectionInfo) {
         String adapter = property(ADAPTER_KEY_MAVEN);
         String user = property(USER_NAME_KEY_MAVEN);
         String pass = property(PASSWORD_KEY_MAVEN);
         String url = property(URL_KEY_MAVEN);
         String driver = property(DRIVER_KEY_MAVEN);
+        // no overrides, do nothing
+        if(adapter == null && user == null && pass == null && url == null && 
driver == null) {
+            return connectionInfo;
+        }
 
         if (connectionInfo == null) {
             // only create a brand new DSI if overrides contains a DB url...
@@ -197,12 +200,12 @@ public class ServerCaseDataSourceInfoProvider implements 
Provider<DataSourceInfo
                 return null;
             }
 
-            connectionInfo = new DataSourceInfo();
+            connectionInfo = new UnitDataSourceDescriptor();
             
connectionInfo.setMinConnections(ConnectionProperties.MIN_CONNECTIONS);
             
connectionInfo.setMaxConnections(ConnectionProperties.MAX_CONNECTIONS);
         }
 
-        connectionInfo = connectionInfo.cloneInfo();
+        connectionInfo = connectionInfo.copy();
         if (adapter != null) {
             connectionInfo.setAdapterClassName(adapter);
         }
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceFactory.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceFactory.java
index 0c387b6d0..8950b5f71 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceFactory.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDataSourceFactory.java
@@ -27,7 +27,7 @@ import java.util.Set;
 
 import javax.sql.DataSource;
 
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.datasource.DataSourceBuilder;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Inject;
@@ -35,12 +35,12 @@ import org.apache.cayenne.di.Inject;
 public class ServerCaseDataSourceFactory {
 
        private DataSource sharedDataSource;
-       private DataSourceInfo dataSourceInfo;
+       private DataSourceDescriptor dataSourceInfo;
        private Map<String, DataSource> dataSources;
        private Set<String> mapsWithDedicatedDataSource;
        private AdhocObjectFactory objectFactory;
 
-       public ServerCaseDataSourceFactory(@Inject DataSourceInfo 
dataSourceInfo, @Inject AdhocObjectFactory objectFactory) {
+       public ServerCaseDataSourceFactory(@Inject DataSourceDescriptor 
dataSourceInfo, @Inject AdhocObjectFactory objectFactory) {
 
                this.objectFactory = objectFactory;
                this.dataSourceInfo = dataSourceInfo;
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDbAdapterProvider.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDbAdapterProvider.java
index ef8e9246d..c24887bd6 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDbAdapterProvider.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseDbAdapterProvider.java
@@ -20,23 +20,21 @@ package org.apache.cayenne.unit.di.server;
 
 import org.apache.cayenne.ConfigurationException;
 import org.apache.cayenne.configuration.server.PkGeneratorFactoryProvider;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.JdbcAdapter;
 import org.apache.cayenne.dba.PkGenerator;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.Provider;
+import org.apache.cayenne.unit.UnitDataSourceDescriptor;
 
 public class ServerCaseDbAdapterProvider implements Provider<JdbcAdapter> {
-
-    private DataSourceInfo dataSourceInfo;
+    private UnitDataSourceDescriptor dataSourceInfo;
     private AdhocObjectFactory objectFactory;
-
     private PkGeneratorFactoryProvider pkGeneratorProvider;
 
     public ServerCaseDbAdapterProvider(
-            @Inject DataSourceInfo dataSourceInfo,
+            @Inject UnitDataSourceDescriptor dataSourceInfo,
             @Inject AdhocObjectFactory objectFactory,
             @Inject PkGeneratorFactoryProvider pkGeneratorProvider) {
         this.dataSourceInfo = dataSourceInfo;
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
index 2429cbc05..70f064e04 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
@@ -58,6 +58,7 @@ import org.apache.cayenne.access.types.VoidType;
 import org.apache.cayenne.configuration.ConfigurationNameMapper;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.DataMapLoader;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.configuration.DefaultConfigurationNameMapper;
 import org.apache.cayenne.configuration.DefaultObjectStoreFactory;
 import org.apache.cayenne.configuration.DefaultRuntimeProperties;
@@ -73,7 +74,6 @@ import org.apache.cayenne.configuration.xml.HandlerFactory;
 import org.apache.cayenne.configuration.xml.NoopDataChannelMetaData;
 import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
 import org.apache.cayenne.configuration.xml.XMLReaderProvider;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.JdbcAdapter;
 import org.apache.cayenne.dba.JdbcPkGenerator;
@@ -104,8 +104,11 @@ import org.apache.cayenne.dba.sybase.SybasePkGenerator;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.ClassLoaderManager;
+import org.apache.cayenne.di.DIRuntimeException;
+import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.Key;
 import org.apache.cayenne.di.Module;
+import org.apache.cayenne.di.Provider;
 import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
 import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
 import org.apache.cayenne.di.spi.DefaultScope;
@@ -125,12 +128,12 @@ import org.apache.cayenne.unit.H2UnitDbAdapter;
 import org.apache.cayenne.unit.HSQLDBUnitDbAdapter;
 import org.apache.cayenne.unit.IngresUnitDbAdapter;
 import org.apache.cayenne.unit.MySQLUnitDbAdapter;
-import org.apache.cayenne.unit.OpenBaseUnitDbAdapter;
 import org.apache.cayenne.unit.OracleUnitDbAdapter;
 import org.apache.cayenne.unit.PostgresUnitDbAdapter;
 import org.apache.cayenne.unit.SQLServerUnitDbAdapter;
 import org.apache.cayenne.unit.SQLiteUnitDbAdapter;
 import org.apache.cayenne.unit.SybaseUnitDbAdapter;
+import org.apache.cayenne.unit.UnitDataSourceDescriptor;
 import org.apache.cayenne.unit.UnitDbAdapter;
 import org.apache.cayenne.unit.di.DataChannelInterceptor;
 import org.apache.cayenne.unit.di.UnitTestLifecycleManager;
@@ -249,7 +252,15 @@ public class ServerCaseModule implements Module {
                 .put("oracle", OracleContainerProvider.class)
                 .put("db2", Db2ContainerProvider.class);
 
-        
binder.bind(DataSourceInfo.class).toProvider(ServerCaseDataSourceInfoProvider.class);
+        
binder.bind(UnitDataSourceDescriptor.class).toProvider(ServerCaseDataSourceDescriptorProvider.class);
+        binder.bind(DataSourceDescriptor.class).toProviderInstance(new 
Provider<>() {
+            @Inject
+            UnitDataSourceDescriptor unitDataSourceDescriptor;
+            @Override
+            public DataSourceDescriptor get() throws DIRuntimeException {
+                return unitDataSourceDescriptor;
+            }
+        });
         
binder.bind(DataSourceFactory.class).to(ServerCaseSharedDataSourceFactory.class);
         
binder.bind(DbAdapter.class).toProvider(ServerCaseDbAdapterProvider.class);
         
binder.bind(JdbcAdapter.class).toProvider(ServerCaseDbAdapterProvider.class);
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseSharedDataSourceFactory.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseSharedDataSourceFactory.java
index a4acf6db8..e2f43dddb 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseSharedDataSourceFactory.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseSharedDataSourceFactory.java
@@ -29,6 +29,7 @@ public class ServerCaseSharedDataSourceFactory implements 
DataSourceFactory {
     private ServerCaseDataSourceFactory factory;
 
     public ServerCaseSharedDataSourceFactory(@Inject 
ServerCaseDataSourceFactory factory) {
+        this.factory = factory;
     }
 
     public DataSource getDataSource(DataNodeDescriptor nodeDescriptor) throws 
Exception {
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/UnitDbAdapterProvider.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/UnitDbAdapterProvider.java
index bc52b6c0e..7cc31c0b6 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/UnitDbAdapterProvider.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/UnitDbAdapterProvider.java
@@ -23,7 +23,7 @@ import java.util.Map;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.ConfigurationException;
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.Injector;
@@ -37,12 +37,12 @@ public class UnitDbAdapterProvider implements 
Provider<UnitDbAdapter> {
 
     private Injector injector;
     private DbAdapter adapter;
-    private DataSourceInfo dataSourceInfo;
+    private DataSourceDescriptor dataSourceInfo;
     private Map<String, String> adapterTypesMap;
 
     public UnitDbAdapterProvider(
             @Inject(TEST_ADAPTERS_MAP) Map<String, String> adapterTypesMap,
-            @Inject DataSourceInfo dataSourceInfo, @Inject DbAdapter adapter,
+            @Inject DataSourceDescriptor dataSourceInfo, @Inject DbAdapter 
adapter,
             @Inject Injector injector) {
         this.dataSourceInfo = dataSourceInfo;
         this.adapterTypesMap = adapterTypesMap;
@@ -53,17 +53,15 @@ public class UnitDbAdapterProvider implements 
Provider<UnitDbAdapter> {
     public UnitDbAdapter get() throws ConfigurationException {
 
         String testAdapterType = adapterTypesMap
-                .get(dataSourceInfo.getAdapterClassName());
+                .get(adapter.getClass().getName());
         if (testAdapterType == null) {
-            throw new IllegalStateException("Unmapped adapter type: "
-                    + dataSourceInfo.getAdapterClassName());
+            throw new IllegalStateException("Unmapped adapter type: " + 
adapter.getClass().getName());
         }
 
         Class<UnitDbAdapter> type;
         try {
             type = (Class<UnitDbAdapter>) Util.getJavaClass(testAdapterType);
-        }
-        catch (ClassNotFoundException e) {
+        } catch (ClassNotFoundException e) {
             throw new CayenneRuntimeException(
                     "Invalid class %s of type AccessStackAdapter",
                     e,
@@ -81,8 +79,7 @@ public class UnitDbAdapterProvider implements 
Provider<UnitDbAdapter> {
             UnitDbAdapter unitAdapter = c.newInstance(adapter);
             injector.injectMembers(unitAdapter);
             return unitAdapter;
-        }
-        catch (Exception e) {
+        } catch (Exception e) {
             throw new ConfigurationException("Error instantiating " + 
testAdapterType, e);
         }
     }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateNodeAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateNodeAction.java
index abf37e5fb..3085d1511 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateNodeAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateNodeAction.java
@@ -23,9 +23,9 @@ import 
org.apache.cayenne.access.dbsync.SkipSchemaUpdateStrategy;
 import org.apache.cayenne.configuration.ConfigurationNode;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.configuration.event.DataNodeEvent;
 import org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dbsync.naming.NameBuilder;
 import org.apache.cayenne.map.event.MapEvent;
 import org.apache.cayenne.modeler.Application;
@@ -87,9 +87,7 @@ public class CreateNodeAction extends CayenneAction {
         DataChannelDescriptor domain = (DataChannelDescriptor) 
mediator.getProject().getRootNode();
 
         DataNodeDescriptor node = buildDataNode(domain);
-
-        DataSourceInfo src = new DataSourceInfo();
-        node.setDataSourceDescriptor(src);
+        node.setDataSourceDescriptor(new DataSourceDescriptor());
 
         // by default create JDBC Node
         
node.setDataSourceFactoryType(XMLPoolingDataSourceFactory.class.getName());
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java
index f2f57ba89..67c04f110 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java
@@ -22,11 +22,11 @@ package org.apache.cayenne.modeler.action;
 import org.apache.cayenne.configuration.ConfigurationNode;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.configuration.event.DataNodeEvent;
 import org.apache.cayenne.configuration.event.QueryEvent;
 import org.apache.cayenne.configuration.server.JNDIDataSourceFactory;
 import org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbsync.naming.NameBuilder;
 import org.apache.cayenne.map.DataMap;
@@ -153,8 +153,7 @@ public class ImportEOModelAction extends CayenneAction {
             if ("JNDI".equalsIgnoreCase(adapter)) {
                 
node.setDataSourceFactoryType(JNDIDataSourceFactory.class.getName());
                 node.setParameters((String) connection.get("serverUrl"));
-            }
-            else {
+            } else {
                 // guess adapter from plugin or driver
                 AdapterMapping adapterDefaults = 
getApplication().getAdapterMapping();
                 String cayenneAdapter = 
adapterDefaults.adapterForEOFPluginOrDriver(
@@ -166,18 +165,14 @@ public class ImportEOModelAction extends CayenneAction {
                                 .getClassLoadingService()
                                 .loadClass(DbAdapter.class, cayenneAdapter);
                         node.setAdapterType(adapterClass.toString());
-                    }
-                    catch (Throwable ex) {
+                    } catch (Throwable ex) {
                         // ignore...
                     }
                 }
 
-                node
-                        
.setDataSourceFactoryType(XMLPoolingDataSourceFactory.class
-                                .getName());
-
-                DataSourceInfo dsi = node.getDataSourceDescriptor();
+                
node.setDataSourceFactoryType(XMLPoolingDataSourceFactory.class.getName());
 
+                DataSourceDescriptor dsi = node.getDataSourceDescriptor();
                 dsi.setDataSourceUrl(keyAsString(connection, "URL"));
                 dsi.setJdbcDriver(keyAsString(connection, "driver"));
                 dsi.setPassword(keyAsString(connection, "password"));
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/AdapterEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/AdapterEditor.java
deleted file mode 100644
index 29dbca9ed..000000000
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/AdapterEditor.java
+++ /dev/null
@@ -1,112 +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
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.modeler.editor.datanode;
-
-import java.awt.Component;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-
-import org.apache.cayenne.configuration.DataNodeDescriptor;
-import org.apache.cayenne.configuration.event.DataNodeEvent;
-import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.event.DataNodeDisplayEvent;
-import org.apache.cayenne.modeler.event.DataNodeDisplayListener;
-import org.apache.cayenne.modeler.util.CayenneController;
-import org.apache.cayenne.swing.BindingBuilder;
-import org.apache.cayenne.swing.ObjectBinding;
-
-/**
- */
-public class AdapterEditor extends CayenneController {
-
-    protected AdapterView view;
-    protected DataNodeDescriptor node;
-    protected ObjectBinding adapterNameBinding;
-
-    public AdapterEditor(CayenneController parent) {
-        super(parent);
-
-        this.view = new AdapterView();
-        initController();
-    }
-
-    protected void initController() {
-        // init bindings
-        BindingBuilder builder = new BindingBuilder(
-                getApplication().getBindingFactory(),
-                this);
-
-        adapterNameBinding = builder.bindToTextField(
-                view.getCustomAdapter(),
-                "adapterName");
-
-        ((ProjectController) getParent())
-                .addDataNodeDisplayListener(new DataNodeDisplayListener() {
-
-                    public void currentDataNodeChanged(DataNodeDisplayEvent e) 
{
-                        refreshView(e.getDataNode());
-                    }
-                });
-
-        getView().addComponentListener(new ComponentAdapter() {
-
-            public void componentShown(ComponentEvent e) {
-                refreshView(node != null ? node : ((ProjectController) 
getParent())
-                        .getCurrentDataNode());
-            }
-        });
-    }
-
-    protected void refreshView(DataNodeDescriptor dataNodeDescriptor) {
-        this.node = dataNodeDescriptor;
-
-        if (dataNodeDescriptor == null) {
-            getView().setVisible(false);
-            return;
-        }
-
-        adapterNameBinding.updateView();
-    }
-
-    public Component getView() {
-        return view;
-    }
-
-    public String getAdapterName() {
-        if (node == null) {
-            return null;
-        }
-        
-        return node.getAdapterType();
-    }
-
-    public void setAdapterName(String name) {
-        if (node == null) {
-            return;
-        }
-
-//        ModelerDbAdapter adapter = new ModelerDbAdapter(name, 
node.getDataSource());
-//        adapter.validate();
-        node.setAdapterType(name);
-        
-        DataNodeEvent e = new DataNodeEvent(AdapterEditor.this, node);
-        ((ProjectController) getParent()).fireDataNodeEvent(e);
-    }
-}
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/AdapterView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/AdapterView.java
deleted file mode 100644
index 1d12ad3dc..000000000
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/AdapterView.java
+++ /dev/null
@@ -1,56 +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
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.modeler.editor.datanode;
-
-import java.awt.BorderLayout;
-
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-import org.apache.cayenne.modeler.util.JTextFieldUndoable;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-public class AdapterView extends JPanel {
-
-    protected JTextField customAdapter;
-
-    public AdapterView() {
-        this.customAdapter = new JTextFieldUndoable();
-
-        // assemble
-
-        DefaultFormBuilder topPanelBuilder = new DefaultFormBuilder(new 
FormLayout(
-                "right:pref, 3dlu, fill:200dlu",
-                ""));
-        topPanelBuilder.setDefaultDialogBorder();
-
-        topPanelBuilder.appendSeparator("DbAdapter Configuration");
-        topPanelBuilder.append("Custom Adapter (optional):", customAdapter);
-
-        setLayout(new BorderLayout());
-        add(topPanelBuilder.getPanel(), BorderLayout.CENTER);
-    }
-
-    public JTextField getCustomAdapter() {
-        return customAdapter;
-    }
-}
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DBCP2DataSourceEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DBCP2DataSourceEditor.java
deleted file mode 100644
index 84a5a8c9d..000000000
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DBCP2DataSourceEditor.java
+++ /dev/null
@@ -1,51 +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
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.modeler.editor.datanode;
-
-import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.swing.BindingBuilder;
-import org.apache.cayenne.swing.BindingDelegate;
-import org.apache.cayenne.swing.ObjectBinding;
-
-import java.awt.Component;
-
-public class DBCP2DataSourceEditor extends DataSourceEditor {
-
-    protected DBCP2DataSourceView view;
-
-    public DBCP2DataSourceEditor(ProjectController controller,
-                                BindingDelegate nodeChangeProcessor) {
-        super(controller, nodeChangeProcessor);
-    }
-
-    protected void prepareBindings(BindingBuilder builder) {
-        this.view = new DBCP2DataSourceView();
-
-        fieldAdapters = new ObjectBinding[1];
-        fieldAdapters[0] = builder.bindToTextField(
-                view.getPropertiesFile(),
-                "node.parameters");
-    }
-
-    public Component getView() {
-        return view;
-    }
-
-}
\ No newline at end of file
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DBCP2DataSourceView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DBCP2DataSourceView.java
deleted file mode 100644
index b8f1c6917..000000000
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DBCP2DataSourceView.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
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.modeler.editor.datanode;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-import org.apache.cayenne.modeler.util.JTextFieldUndoable;
-
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-import java.awt.BorderLayout;
-
-public class DBCP2DataSourceView extends JPanel {
-
-    protected JTextField propertiesFile;
-
-    public DBCP2DataSourceView() {
-
-        propertiesFile = new JTextFieldUndoable();
-
-        // assemble
-        FormLayout layout = new FormLayout("right:80dlu, 3dlu, fill:200dlu", 
"");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-
-        builder.appendSeparator("Apache DBCP2 Configuration");
-
-        builder.append("DBCP2 Properties File:", propertiesFile);
-
-        setLayout(new BorderLayout());
-        add(builder.getPanel(), BorderLayout.CENTER);
-    }
-
-    public JTextField getPropertiesFile() {
-        return propertiesFile;
-    }
-}
\ No newline at end of file
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DataNodeEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DataNodeEditor.java
index ab5c5496c..c26480ad8 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DataNodeEditor.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DataNodeEditor.java
@@ -38,8 +38,6 @@ public class DataNodeEditor extends CayenneController {
         
         this.view = new JTabbedPane();
         view.addTab("Main", new JScrollPane(new 
MainDataNodeEditor(parent,this).getView()));
-        view.addTab("Adapter", new AdapterEditor(parent).getView());
-        view.addTab("Password Encoder", new 
PasswordEncoderEditor(parent).getView()) ;
     }
 
     public Component getView() {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DataSourceEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DataSourceEditor.java
index 947879d8b..051b68b9d 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DataSourceEditor.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/DataSourceEditor.java
@@ -42,8 +42,6 @@ public abstract class DataSourceEditor extends 
CayenneController {
         initBindings();
     }
 
-   
-
     public DataNodeDescriptor getNode() {
         return node;
     }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JDBCDataSourceEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JDBCDataSourceEditor.java
index 163e323be..473602276 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JDBCDataSourceEditor.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JDBCDataSourceEditor.java
@@ -22,7 +22,7 @@ package org.apache.cayenne.modeler.editor.datanode;
 import java.awt.Component;
 
 import org.apache.cayenne.configuration.DataNodeDescriptor;
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.modeler.CayenneModelerController;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.pref.DBConnectionInfo;
@@ -35,10 +35,8 @@ public class JDBCDataSourceEditor extends DataSourceEditor {
 
     protected JDBCDataSourceView view;
 
-    public JDBCDataSourceEditor(ProjectController parent,
-            BindingDelegate nodeChangeProcessor) {
+    public JDBCDataSourceEditor(ProjectController parent, BindingDelegate 
nodeChangeProcessor) {
         super(parent, nodeChangeProcessor);
-
     }
 
     public Component getView() {
@@ -49,7 +47,7 @@ public class JDBCDataSourceEditor extends DataSourceEditor {
     public void setNode(DataNodeDescriptor node) {
         if (!Util.nullSafeEquals(getNode(), node)) {
             if (node.getDataSourceDescriptor() == null) {
-                node.setDataSourceDescriptor(new DataSourceInfo());
+                node.setDataSourceDescriptor(new DataSourceDescriptor());
             }
             super.setNode(node);
         }
@@ -91,7 +89,7 @@ public class JDBCDataSourceEditor extends DataSourceEditor {
             return;
         }
 
-        DataSourceInfo projectDSI = getNode().getDataSourceDescriptor();
+        DataSourceDescriptor projectDataSourceDescriptor = 
getNode().getDataSourceDescriptor();
 
         ProjectController parent = (ProjectController) getParent();
         String key = parent.getDataNodePreferences().getLocalDataSource();
@@ -106,16 +104,14 @@ public class JDBCDataSourceEditor extends 
DataSourceEditor {
             .getObject(key);
 
         if (dataSource != null) {
-            if (dataSource.copyTo(projectDSI)) {
+            if (dataSource.copyTo(projectDataSourceDescriptor)) {
                 refreshView();
                 super.nodeChangeProcessor.modelUpdated(null, null, null);
                 mainController.updateStatus(null);
-            }
-            else {
+            } else {
                 mainController.updateStatus("DataNode is up to date...");
             }
-        }
-        else {
+        } else {
             mainController.updateStatus("Invalid Local DataSource selected for 
node...");
         }
     }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JNDIDataSourceView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JNDIDataSourceView.java
deleted file mode 100644
index c6a7cb79d..000000000
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/JNDIDataSourceView.java
+++ /dev/null
@@ -1,56 +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
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.modeler.editor.datanode;
-
-import java.awt.BorderLayout;
-
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-import org.apache.cayenne.modeler.util.JTextFieldUndoable;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-public class JNDIDataSourceView extends JPanel {
-
-    protected JTextField jndiPath;
-
-    public JNDIDataSourceView() {
-
-        jndiPath = new JTextFieldUndoable();
-
-        // assemble
-        FormLayout layout = new FormLayout("right:80dlu, 3dlu, fill:200dlu", 
"");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-
-        builder.appendSeparator("JNDI Configuration");
-
-        builder.append("JNDI Location:", jndiPath);
-
-        this.setLayout(new BorderLayout());
-        this.add(builder.getPanel(), BorderLayout.CENTER);
-    }
-
-    public JTextField getJndiPath() {
-        return jndiPath;
-    }
-}
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/MainDataNodeEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/MainDataNodeEditor.java
index 35a6b4659..5cb47cb65 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/MainDataNodeEditor.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/MainDataNodeEditor.java
@@ -35,7 +35,6 @@ import 
org.apache.cayenne.access.dbsync.ThrowOnPartialSchemaStrategy;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
 import org.apache.cayenne.configuration.event.DataNodeEvent;
-import org.apache.cayenne.configuration.server.JNDIDataSourceFactory;
 import org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.dialog.pref.PreferenceDialog;
@@ -55,12 +54,9 @@ import org.apache.cayenne.validation.ValidationException;
 public class MainDataNodeEditor extends CayenneController {
 
        protected static final String NO_LOCAL_DATA_SOURCE = "Select DataSource 
for Local Work...";
-       public static final String DBCP_DATA_SOURCE_FACTORY = 
"org.apache.cayenne.configuration.server.DBCPDataSourceFactory";
 
        private final static String[] STANDARD_DATA_SOURCE_FACTORIES = new 
String[] {
-               XMLPoolingDataSourceFactory.class.getName(),
-                       JNDIDataSourceFactory.class.getName(),
-            DBCP_DATA_SOURCE_FACTORY
+               XMLPoolingDataSourceFactory.class.getName()
        };
 
        private final static String[] STANDARD_SCHEMA_UPDATE_STRATEGY = new 
String[] {
@@ -192,10 +188,11 @@ public class MainDataNodeEditor extends CayenneController 
{
 
                builder.setDelegate(nodeChangeProcessor);
 
-               bindings = new ObjectBinding[3];
+               bindings = new ObjectBinding[4];
                bindings[0] = builder.bindToTextField(view.getDataNodeName(), 
"nodeName");
                bindings[1] = builder.bindToComboSelection(view.getFactories(), 
"factoryName");
                bindings[2] = 
builder.bindToComboSelection(view.getSchemaUpdateStrategy(), 
"schemaUpdateStrategy");
+               bindings[3] = builder.bindToTextField(view.getCustomAdapter(), 
"adapterName");
 
                // one way bindings
                builder.bindToAction(view.getConfigLocalDataSources(), 
"dataSourceConfigAction()");
@@ -252,20 +249,13 @@ public class MainDataNodeEditor extends CayenneController 
{
        protected void showDataSourceSubview(String factoryName) {
 
                DataSourceEditor c = datasourceEditors.get(factoryName);
-
                // create subview dynamically...
                if (c == null) {
-
                        if 
(XMLPoolingDataSourceFactory.class.getName().equals(factoryName)) {
                                c = new 
JDBCDataSourceEditor((ProjectController) getParent(), nodeChangeProcessor);
-                       } else if 
(JNDIDataSourceFactory.class.getName().equals(factoryName)) {
-                               c = new 
JNDIDataSourceEditor((ProjectController) getParent(), nodeChangeProcessor);
-                       } else if 
(DBCP_DATA_SOURCE_FACTORY.equals(factoryName)) {
-                               c = new 
DBCP2DataSourceEditor((ProjectController) getParent(), nodeChangeProcessor);
                        } else {
                                // special case - no detail view, just show it 
and bail..
                                defaultSubeditor.setNode(node);
-                               disabledTab("default");
                                
view.getDataSourceDetailLayout().show(view.getDataSourceDetail(), "default");
                                return;
                        }
@@ -279,19 +269,15 @@ public class MainDataNodeEditor extends CayenneController 
{
 
                // this will refresh subview...
                c.setNode(node);
-               disabledTab(factoryName);
                // display the right subview...
                
view.getDataSourceDetailLayout().show(view.getDataSourceDetail(), factoryName);
-
        }
 
-       protected void disabledTab(String name) {
-
-               if (name.equals(STANDARD_DATA_SOURCE_FACTORIES[0])) {
-                       tabbedPaneController.getTabComponent().setEnabledAt(2, 
true);
-               } else {
-                       tabbedPaneController.getTabComponent().setEnabledAt(2, 
false);
-               }
+       public String getAdapterName() {
+               return node.getAdapterType();
        }
 
+       public void setAdapterName(String name) {
+               node.setAdapterType(name);
+       }
 }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/MainDataNodeView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/MainDataNodeView.java
index 7c22c6117..86d690dd3 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/MainDataNodeView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/MainDataNodeView.java
@@ -26,17 +26,12 @@ import org.apache.cayenne.modeler.util.JTextFieldUndoable;
 
 import javax.swing.JButton;
 import javax.swing.JComboBox;
-import javax.swing.JDialog;
 import javax.swing.JLabel;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
 import java.awt.BorderLayout;
 import java.awt.CardLayout;
 import java.awt.Font;
-import java.awt.event.ActionEvent;
-
-import static 
org.apache.cayenne.modeler.editor.datanode.MainDataNodeEditor.DBCP_DATA_SOURCE_FACTORY;
 
 /**
  * A view for the main DataNode editor tab.
@@ -48,6 +43,7 @@ public class MainDataNodeView extends JPanel {
     protected JComboBox<String> factories;
     protected JPanel dataSourceDetail;
     protected CardLayout dataSourceDetailLayout;
+    protected JTextFieldUndoable customAdapter;
     protected JComboBox<String> localDataSources;
     protected JButton configLocalDataSources;
     protected JComboBox<String> schemaUpdateStrategy;
@@ -59,14 +55,14 @@ public class MainDataNodeView extends JPanel {
 
         this.factories = 
Application.getWidgetFactory().createUndoableComboBox();
 
-        factories.addActionListener(this::showWarningMessage);
-
         this.localDataSources = 
Application.getWidgetFactory().createUndoableComboBox();
 
         this.schemaUpdateStrategy = 
Application.getWidgetFactory().createUndoableComboBox();
         this.dataSourceDetailLayout = new CardLayout();
         this.dataSourceDetail = new JPanel(dataSourceDetailLayout);
 
+        this.customAdapter = new JTextFieldUndoable();
+
         this.configLocalDataSources = new JButton("...");
         this.configLocalDataSources.setToolTipText("configure local 
DataSource");
 
@@ -88,8 +84,10 @@ public class MainDataNodeView extends JPanel {
         Font font = new Font(getFont().getName(), Font.PLAIN, 
getFont().getSize() - 2);
         label.setFont(font);
         builderForLabel.append(label);
-
         topPanelBuilder.append("", builderForLabel.getPanel(), 3);
+
+        topPanelBuilder.append("Custom Adapter (optional):", customAdapter, 3);
+
         topPanelBuilder.append(
                 "Local DataSource (opt.):",
                 localDataSources,
@@ -129,12 +127,7 @@ public class MainDataNodeView extends JPanel {
         return configLocalDataSources;
     }
 
-    private void showWarningMessage(ActionEvent e){
-        if(DBCP_DATA_SOURCE_FACTORY.equals(factories.getSelectedItem())) {
-            JDialog dialog = new JOptionPane("DPCPDataSourceFactory is 
deprecated since 4.1", JOptionPane.WARNING_MESSAGE)
-                    .createDialog("Warning");
-            dialog.setAlwaysOnTop(true);
-            dialog.setVisible(true);
-        }
+    public JTextFieldUndoable getCustomAdapter() {
+        return customAdapter;
     }
 }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/PasswordEncoderEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/PasswordEncoderEditor.java
deleted file mode 100644
index 6ce635469..000000000
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/PasswordEncoderEditor.java
+++ /dev/null
@@ -1,200 +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
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.modeler.editor.datanode;
-
-import java.awt.Component;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-
-import javax.swing.JOptionPane;
-
-import org.apache.cayenne.configuration.DataNodeDescriptor;
-import org.apache.cayenne.configuration.event.DataNodeEvent;
-import org.apache.cayenne.conn.DataSourceInfo;
-import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.event.DataNodeDisplayEvent;
-import org.apache.cayenne.modeler.event.DataNodeDisplayListener;
-import org.apache.cayenne.modeler.util.CayenneController;
-import org.apache.cayenne.swing.BindingBuilder;
-import org.apache.cayenne.swing.BindingDelegate;
-import org.apache.cayenne.swing.ObjectBinding;
-
-public class PasswordEncoderEditor extends CayenneController {
-
-    protected DataNodeDescriptor node;
-    protected ObjectBinding[] bindings;
-    protected PasswordEncoderView view;
-    protected BindingDelegate nodeChangeProcessor;
-
-    public PasswordEncoderEditor(CayenneController parent) {
-
-        super(parent);
-
-        this.view = new PasswordEncoderView();
-
-        this.nodeChangeProcessor = new BindingDelegate() {
-
-            public void modelUpdated(
-                    ObjectBinding binding,
-                    Object oldValue,
-                    Object newValue) {
-
-                DataNodeEvent e = new 
DataNodeEvent(PasswordEncoderEditor.this, node);
-                ((ProjectController) getParent()).fireDataNodeEvent(e);
-            }
-        };
-
-        initController();
-    }
-
-    protected void initController() {
-        BindingBuilder builder = new BindingBuilder(
-                getApplication().getBindingFactory(),
-                this);
-
-        builder.setDelegate(nodeChangeProcessor);
-
-        bindings = new ObjectBinding[4];
-
-        bindings[0] = builder.bindToComboSelection(
-                view.getPasswordEncoder(),
-                "node.dataSourceDescriptor.passwordEncoderClass");
-        bindings[1] = builder.bindToTextField(
-                view.getPasswordKey(),
-                "node.dataSourceDescriptor.passwordEncoderKey");
-        bindings[2] = builder.bindToComboSelection(
-                view.getPasswordLocation(),
-                "node.dataSourceDescriptor.passwordLocation");
-        bindings[3] = builder.bindToTextField(
-                view.getPasswordSource(),
-                "node.dataSourceDescriptor.passwordSource");
-
-        ((ProjectController) getParent())
-                .addDataNodeDisplayListener(new DataNodeDisplayListener() {
-
-                    public void currentDataNodeChanged(DataNodeDisplayEvent e) 
{
-                        refreshView(e.getDataNode());
-                    }
-                });
-
-        getView().addComponentListener(new ComponentAdapter() {
-
-            public void componentShown(ComponentEvent e) {
-                refreshView(node != null ? node : ((ProjectController) 
getParent())
-                        .getCurrentDataNode());
-            }
-        });
-
-        builder
-                .bindToAction(
-                        view.getPasswordEncoder(),
-                        "validatePasswordEncoderAction()");
-        builder.bindToAction(
-                view.getPasswordLocation(),
-                "passwordLocationChangedAction()");
-
-    }
-
-    protected void refreshView(DataNodeDescriptor dataNodeDescriptor) {
-        this.node = dataNodeDescriptor;
-
-        if (dataNodeDescriptor == null || 
dataNodeDescriptor.getDataSourceDescriptor() == null) {
-            getView().setVisible(false);
-            return;
-        }
-
-        for (ObjectBinding binding : bindings) {
-            binding.updateView();
-        }
-    }
-
-    public void validatePasswordEncoderAction() {
-        if (node == null || node.getDataSourceDescriptor() == null)
-            return;
-
-        DataSourceInfo dsi = node.getDataSourceDescriptor();
-
-        if 
(!view.getPasswordEncoder().getSelectedItem().equals(dsi.getPasswordEncoderClass()))
-            return;
-
-        if (dsi.getPasswordEncoder() == null) {
-            JOptionPane
-                    .showMessageDialog(
-                            getView(),
-                            "A valid Password Encoder should be specified 
(check your CLASSPATH).",
-                            "Invalid Password Encoder",
-                            JOptionPane.ERROR_MESSAGE);
-        }
-    }
-
-    private void updatePasswordElements(
-            boolean isPasswordFieldEnabled,
-            boolean isPasswordLocationEnabled,
-            String passwordText,
-            String passwordLocationLabel,
-            String passwordLocationText) {
-        view.getPasswordSource().setEnabled(isPasswordLocationEnabled);
-        view.getPasswordSourceLabel().setText(passwordLocationLabel);
-        view.getPasswordSource().setText(passwordLocationText);
-
-    }
-
-    public void passwordLocationChangedAction() {
-        if (node == null || node.getDataSourceDescriptor() == null)
-            return;
-
-        DataSourceInfo dsi = node.getDataSourceDescriptor();
-
-        String selectedItem = (String) 
view.getPasswordLocation().getSelectedItem();
-
-        if (selectedItem.equals(DataSourceInfo.PASSWORD_LOCATION_CLASSPATH))
-            updatePasswordElements(
-                    true,
-                    true,
-                    dsi.getPassword(),
-                    "Password Filename:",
-                    dsi.getPasswordSourceFilename());
-        else if 
(selectedItem.equals(DataSourceInfo.PASSWORD_LOCATION_EXECUTABLE))
-            updatePasswordElements(false, true, null, "Password Executable:", 
dsi
-                    .getPasswordSourceExecutable());
-        else if (selectedItem.equals(DataSourceInfo.PASSWORD_LOCATION_MODEL))
-            updatePasswordElements(
-                    true,
-                    false,
-                    dsi.getPassword(),
-                    "Password Source:",
-                    dsi.getPasswordSourceModel());
-        else if (selectedItem.equals(DataSourceInfo.PASSWORD_LOCATION_URL))
-            updatePasswordElements(false, true, null, "Password URL:", dsi
-                    .getPasswordSourceUrl());
-    }
-
-    public Component getView() {
-        return view;
-    }
-
-    public DataNodeDescriptor getNode() {
-        return node;
-    }
-
-    public void setNode(DataNodeDescriptor node) {
-        this.node = node;
-    }
-
-}
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/PasswordEncoderView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/PasswordEncoderView.java
deleted file mode 100644
index 421a68af3..000000000
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/datanode/PasswordEncoderView.java
+++ /dev/null
@@ -1,182 +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
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.modeler.editor.datanode;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.DefaultListCellRenderer;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-import org.apache.cayenne.configuration.PasswordEncoding;
-import org.apache.cayenne.conn.DataSourceInfo;
-import org.apache.cayenne.modeler.Application;
-import org.apache.cayenne.modeler.util.JTextFieldUndoable;
-
-import com.jgoodies.forms.builder.PanelBuilder;
-import com.jgoodies.forms.layout.CellConstraints;
-import com.jgoodies.forms.layout.FormLayout;
-
-public class PasswordEncoderView extends JPanel {
-
-    protected JComboBox passwordEncoder;
-    protected JComboBox passwordLocation;
-    protected JTextField passwordKey;
-    protected JTextField passwordSource;
-    protected JLabel passwordSourceLabel;
-
-    private static final String PASSWORD_CLASSPATH = "Classpath Search (File 
System)";
-    private static final String PASSWORD_EXECUTABLE = "Executable Program";
-    private static final String PASSWORD_MODEL = "Cayenne Model";
-    private static final String PASSWORD_URL = "URL (file:, http:, etc)";
-
-    private static final Object[] PASSWORD_LOCATIONS = new Object[] {
-            DataSourceInfo.PASSWORD_LOCATION_MODEL,
-            DataSourceInfo.PASSWORD_LOCATION_CLASSPATH,
-            DataSourceInfo.PASSWORD_LOCATION_EXECUTABLE,
-            DataSourceInfo.PASSWORD_LOCATION_URL
-    };
-
-    private static final Map<String, String> passwordSourceLabels = new 
TreeMap<String, String>();
-
-    static {
-        passwordSourceLabels.put(DataSourceInfo.PASSWORD_LOCATION_MODEL, 
PASSWORD_MODEL);
-        passwordSourceLabels.put(
-                DataSourceInfo.PASSWORD_LOCATION_CLASSPATH,
-                PASSWORD_CLASSPATH);
-        passwordSourceLabels.put(
-                DataSourceInfo.PASSWORD_LOCATION_EXECUTABLE,
-                PASSWORD_EXECUTABLE);
-        passwordSourceLabels.put(DataSourceInfo.PASSWORD_LOCATION_URL, 
PASSWORD_URL);
-    }
-
-    final class PasswordLocationRenderer extends DefaultListCellRenderer {
-
-        public Component getListCellRendererComponent(
-                JList list,
-                Object object,
-                int arg2,
-                boolean arg3,
-                boolean arg4) {
-            if (object != null)
-                object = passwordSourceLabels.get(object);
-            else
-                object = PASSWORD_MODEL;
-
-            return super.getListCellRendererComponent(list, object, arg2, 
arg3, arg4);
-        }
-    }
-
-    public PasswordEncoderView() {
-
-        this.passwordEncoder = 
Application.getWidgetFactory().createUndoableComboBox();
-        this.passwordLocation = 
Application.getWidgetFactory().createUndoableComboBox();
-        this.passwordSource = new JTextFieldUndoable();
-        this.passwordKey = new JTextFieldUndoable();
-
-        // init combo box choices
-        passwordEncoder.setModel(new DefaultComboBoxModel(
-                PasswordEncoding.standardEncoders));
-        passwordEncoder.setEditable(true);
-
-        passwordLocation = 
Application.getWidgetFactory().createUndoableComboBox();
-        passwordLocation.setRenderer(new PasswordLocationRenderer());
-
-        DefaultComboBoxModel passwordLocationModel = new DefaultComboBoxModel(
-                PASSWORD_LOCATIONS);
-
-        passwordLocation.setModel(passwordLocationModel);
-
-        CellConstraints cc = new CellConstraints();
-
-        FormLayout layout = new FormLayout(
-                "right:80dlu, 3dlu, fill:50dlu, 3dlu, fill:74dlu, 3dlu, 
fill:70dlu", // Columns
-                "p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 
3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p"); // Rows
-
-        PanelBuilder builder = new PanelBuilder(layout);
-        builder.setDefaultDialogBorder();
-
-        builder.addSeparator("Encoder", cc.xywh(1, 1, 7, 1));
-
-        builder.addLabel("Password Encoder:", cc.xy(1, 11));
-        builder.add(passwordEncoder, cc.xywh(3, 11, 5, 1));
-
-        builder.addLabel("Password Encoder Key:", cc.xy(1, 13));
-        builder.add(passwordKey, cc.xywh(3, 13, 5, 1));
-
-        builder.addLabel("Note: Cayenne supplied encoders do not use a key.", 
cc.xywh(
-                3,
-                15,
-                5,
-                1));
-
-        builder.addLabel("Password Location:", cc.xy(1, 17));
-        builder.add(passwordLocation, cc.xywh(3, 17, 5, 1));
-
-        passwordSourceLabel = builder.addLabel("Password Source:", cc.xy(1, 
19));
-        builder.add(passwordSource, cc.xywh(3, 19, 5, 1));
-
-        this.setLayout(new BorderLayout());
-        this.add(builder.getPanel(), BorderLayout.CENTER);
-
-    }
-
-    /**
-     * @return the passwordEncoder
-     */
-    public JComboBox getPasswordEncoder() {
-        return passwordEncoder;
-    }
-
-    /**
-     * @return the passwordLocation
-     */
-    public JComboBox getPasswordLocation() {
-        return passwordLocation;
-    }
-
-    /**
-     * @return the passwordKey
-     */
-    public JTextField getPasswordKey() {
-        return passwordKey;
-    }
-
-    /**
-     * @return the passwordSource
-     */
-    public JTextField getPasswordSource() {
-        return passwordSource;
-    }
-
-    /**
-     * @return the passwordLocationLabel
-     */
-    public JLabel getPasswordSourceLabel() {
-        return passwordSourceLabel;
-    }
-
-}
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DBConnectionInfo.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DBConnectionInfo.java
index f8eef2ad6..225c7d609 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DBConnectionInfo.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DBConnectionInfo.java
@@ -25,8 +25,8 @@ import java.util.prefs.Preferences;
 
 import javax.sql.DataSource;
 
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.configuration.server.DbAdapterFactory;
-import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.datasource.DriverDataSource;
 import org.apache.cayenne.dba.AutoAdapter;
 import org.apache.cayenne.dba.DbAdapter;
@@ -274,7 +274,7 @@ public class DBConnectionInfo extends CayennePreference {
         * an adapter update here. </i>
         * </p>
         */
-       public boolean copyTo(final DataSourceInfo dataSourceInfo) {
+       public boolean copyTo(final DataSourceDescriptor dataSourceInfo) {
                boolean updated = false;
 
                if (!Util.nullSafeEquals(dataSourceInfo.getDataSourceUrl(), 
getUrl())) {
@@ -300,7 +300,7 @@ public class DBConnectionInfo extends CayennePreference {
                return updated;
        }
 
-       public boolean copyFrom(final DataSourceInfo dataSourceInfo) {
+       public boolean copyFrom(final DataSourceDescriptor dataSourceInfo) {
                boolean updated = false;
 
                if (!Util.nullSafeEquals(dataSourceInfo.getDataSourceUrl(), 
getUrl())) {
diff --git 
a/modeler/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/action/CreateNodeActionTest.java
 
b/modeler/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/action/CreateNodeActionTest.java
index dbd91fe06..5821e3e21 100644
--- 
a/modeler/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/action/CreateNodeActionTest.java
+++ 
b/modeler/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/action/CreateNodeActionTest.java
@@ -19,10 +19,9 @@
 
 package org.apache.cayenne.modeler.action;
 
-
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
-import org.apache.cayenne.conn.DataSourceInfo;
+import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.junit.Test;
 
 import static org.junit.Assert.assertNotNull;
@@ -36,8 +35,7 @@ public class CreateNodeActionTest {
 
         try {
             action = new CreateNodeAction(null);
-        }
-        catch (InternalError e) {
+        } catch (InternalError e) {
             // caused by headless server running the tests ...
             // TODO: setup test environment DISPLAY variable
             return;
@@ -50,10 +48,9 @@ public class CreateNodeActionTest {
         assertNotNull(node);
         assertNotNull(node.getName());
 
-        DataSourceInfo ds1 = new DataSourceInfo();
+        DataSourceDescriptor ds1 = new DataSourceDescriptor();
         node.setDataSourceDescriptor(ds1);
 
-        assertSame("Project DataNode must not wrap the DataSource", ds1, node
-                .getDataSourceDescriptor());
+        assertSame("Project DataNode must not wrap the DataSource", ds1, 
node.getDataSourceDescriptor());
     }
 }

Reply via email to