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
commit 585a39a9234ed42d9650012e7dbb1ddd1e4ed3b8 Author: Nikita Timofeev <[email protected]> AuthorDate: Mon Jul 25 19:09:35 2022 +0300 Fix DbAdaptor creation in the DB generator --- .../modeler/dialog/db/gen/DBGeneratorOptions.java | 5 +- .../cayenne/modeler/pref/DBConnectionInfo.java | 108 +++++++++++++++++---- 2 files changed, 91 insertions(+), 22 deletions(-) diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/gen/DBGeneratorOptions.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/gen/DBGeneratorOptions.java index 0261d23e8..ebbce5a3d 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/gen/DBGeneratorOptions.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/gen/DBGeneratorOptions.java @@ -73,6 +73,8 @@ public class DBGeneratorOptions extends CayenneController { this.tables = new TableSelectorController(parent); this.view = new DBGeneratorOptionsView(tables.getView()); this.connectionInfo = new DBConnectionInfo(); + // DataSource may not be initialized, so warn connection wizard + this.connectionInfo.setAllowDataSourceFailure(true); this.generatorDefaults = new DBGeneratorDefaults(parent .getPreferenceForProject() .node("DbGenerator")); @@ -162,8 +164,7 @@ public class DBGeneratorOptions extends CayenneController { */ protected void prepareGenerator() { try { - DbAdapter adapter = connectionInfo.makeAdapter(getApplication() - .getClassLoadingService()); + DbAdapter adapter = connectionInfo.makeAdapter(getApplication().getClassLoadingService()); generators = new ArrayList<>(); for (DataMap dataMap : dataMaps) { this.generators.add(new DbGenerator( 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 225c7d609..d2206df0c 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 @@ -19,18 +19,21 @@ package org.apache.cayenne.modeler.pref; +import java.io.PrintWriter; +import java.sql.Connection; import java.sql.Driver; import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.logging.Logger; import java.util.prefs.Preferences; import javax.sql.DataSource; +import org.apache.cayenne.configuration.DataNodeDescriptor; import org.apache.cayenne.configuration.DataSourceDescriptor; import org.apache.cayenne.configuration.server.DbAdapterFactory; import org.apache.cayenne.datasource.DriverDataSource; -import org.apache.cayenne.dba.AutoAdapter; import org.apache.cayenne.dba.DbAdapter; -import org.apache.cayenne.di.AdhocObjectFactory; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ClassLoadingService; import org.apache.cayenne.pref.CayennePreference; @@ -58,6 +61,8 @@ public class DBConnectionInfo extends CayennePreference { private Preferences dbConnectionInfoPreferences; + private boolean allowDataSourceFailure; + public DBConnectionInfo() { dbConnectionInfoPreferences = getCayennePreference().node(DB_CONNECTION_INFO); setCurrentPreference(dbConnectionInfoPreferences); @@ -90,6 +95,10 @@ public class DBConnectionInfo extends CayennePreference { } } + public void setAllowDataSourceFailure(boolean allowDataSourceFailure) { + this.allowDataSourceFailure = allowDataSourceFailure; + } + @Override public void saveObjectPreference() { if (getCurrentPreference() != null) { @@ -182,21 +191,12 @@ public class DBConnectionInfo extends CayennePreference { * Creates a DbAdapter based on configured values. */ public DbAdapter makeAdapter(final ClassLoadingService classLoader) throws Exception { - String adapterClassName = getDbAdapter(); - Application appInstance = Application.getInstance(); - - if (adapterClassName == null || AutoAdapter.class.getName().equals(adapterClassName)) { - return appInstance.getInjector().getInstance(DbAdapterFactory.class) - .createAdapter(null, makeDataSource(classLoader)); - } - - try { - return appInstance.getInjector().getInstance(AdhocObjectFactory.class) - .newInstance(DbAdapter.class, adapterClassName); - } catch (Throwable th) { - th = Util.unwindException(th); - throw new Exception("DbAdapter load error: " + th.getLocalizedMessage()); - } + DataNodeDescriptor descriptor = new DataNodeDescriptor(); + descriptor.setAdapterType(getDbAdapter()); + DataSource dataSource = makeDataSource(classLoader); + return Application.getInstance().getInjector() + .getInstance(DbAdapterFactory.class) + .createAdapter(descriptor, dataSource); } /** @@ -208,10 +208,16 @@ public class DBConnectionInfo extends CayennePreference { // validate... if (getJdbcDriver() == null) { + if(allowDataSourceFailure) { + return new DeferredDataSource(classLoader); + } throw new SQLException("No JDBC driver set."); } if (getUrl() == null) { + if(allowDataSourceFailure) { + return new DeferredDataSource(classLoader); + } throw new SQLException("No DB URL set."); } @@ -220,13 +226,12 @@ public class DBConnectionInfo extends CayennePreference { } // load driver... - Driver driver; + Driver driver = null; try { driver = classLoader.loadClass(Driver.class, getJdbcDriver()).getDeclaredConstructor().newInstance(); } catch (Throwable th) { - th = Util.unwindException(th); - throw new SQLException("Driver load error: " + th.getLocalizedMessage()); + throw new SQLException("Driver load error: " + Util.unwindException(th).getLocalizedMessage()); } return new DriverDataSource(driver, getUrl(), getUserName(), getPassword()); @@ -325,4 +330,67 @@ public class DBConnectionInfo extends CayennePreference { return updated; } + + private class DeferredDataSource implements DataSource { + + private final ClassLoadingService classLoader; + + public DeferredDataSource(ClassLoadingService classLoader) { + this.classLoader = classLoader; + } + + DataSource getDeferredDataSource() throws SQLException { + allowDataSourceFailure = false; + return makeDataSource(classLoader); + } + + @Override + public Connection getConnection() throws SQLException { + return getDeferredDataSource().getConnection(); + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + return getDeferredDataSource().getConnection(username, password); + } + + @Override + public PrintWriter getLogWriter() throws SQLException { + return getDeferredDataSource().getLogWriter(); + } + + @Override + public void setLogWriter(PrintWriter out) throws SQLException { + getDeferredDataSource().setLogWriter(out); + } + + @Override + public void setLoginTimeout(int seconds) throws SQLException { + getDeferredDataSource().setLoginTimeout(seconds); + } + + @Override + public int getLoginTimeout() throws SQLException { + return getDeferredDataSource().getLoginTimeout(); + } + + @Override + public <T> T unwrap(Class<T> iface) throws SQLException { + return getDeferredDataSource().unwrap(iface); + } + + @Override + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return getDeferredDataSource().isWrapperFor(iface); + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + try { + return getDeferredDataSource().getParentLogger(); + } catch (SQLException e) { + throw new SQLFeatureNotSupportedException(e); + } + } + } } \ No newline at end of file
