diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java index 43c834e46..338cd1491 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java @@ -853,7 +853,7 @@ public class JDBCConfigurationImpl /** * Free the data sources. */ - public void close() { + protected void preClose() { if (dataSource != null) { getDBDictionaryInstance().closeDataSource(dataSource); connectionFactory.set(null, true); // so super doesn't close it @@ -862,7 +862,7 @@ public class JDBCConfigurationImpl getDBDictionaryInstance().closeDataSource(dataSource); connectionFactory2.set(null, true); // so super doesn't close it } - super.close(); + super.preClose(); } protected boolean isInvalidProperty(String propName) { diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java index afb993e45..ad5431282 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java @@ -1411,10 +1411,10 @@ public class OpenJPAConfigurationImpl getRemoteCommitEventManager(); } - public void close() { + protected void preClose() { ImplHelper.close(metaRepository); ImplHelper.close(remoteEventManager); - super.close(); + super.preClose(); } public Log getConfigurationLog() { diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java index 5d855064f..97fcc70e7 100644 --- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java +++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java @@ -329,7 +329,11 @@ public class ConfigurationImpl /** * Closes all closeable values and plugins. */ - public void close() { + public final void close() { + ProductDerivations.beforeClose(this); + + preClose(); + ObjectValue val; for (int i = 0; i < _vals.size(); i++) { if (_vals.get(i) instanceof Closeable) { @@ -350,6 +354,16 @@ public class ConfigurationImpl } } } + + /** + * Invoked by final method {@link #close} after invoking the + * {@link ProductDerivation#beforeConfigurationClose} callbacks + * but before performing internal close operations. + * + * @since 0.9.7 + */ + protected void preClose() { + } /////////////////////////// // BeanInfo implementation diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java index b0b4178f7..d5a96001e 100644 --- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java +++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java @@ -150,6 +150,22 @@ public class ProductDerivations { } } + /** + * Called as the first step of a Configuration's close() method. + * Exceptions are swallowed. + * + * @since 0.9.7 + */ + public static void beforeClose(Configuration conf) { + for (int i = 0; i < _derivations.length; i++) { + try { + _derivations[i].beforeConfigurationClose(conf); + } catch (Exception e) { + conf.getConfigurationLog().warn(_loc.get("before-close-ex"), e); + } + } + } + /** * Load the given given resource, or return false if it is not a resource * this provider understands. The given class loader may be null. diff --git a/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties b/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties index 3698981b5..f0732def5 100644 --- a/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties +++ b/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties @@ -84,6 +84,8 @@ no-product-derivations: Your system is missing product derivations. Product \ is an overly-restrictive security manager.\n{1} bad-product-derivations: Some product derivations are being skipped. For \ information about product derivation status, run:\njava {0} +before-close-ex: An exception occurred during ProductDerivations.beforeClose().\ + This exception will be ignored, and is logged along with this message. Log-name: Log factory Log-desc: LogFactory and configuration diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/ConfigurationTestProductDerivation.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/ConfigurationTestProductDerivation.java index e857c6590..ae075e5f1 100644 --- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/ConfigurationTestProductDerivation.java +++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/ConfigurationTestProductDerivation.java @@ -22,6 +22,7 @@ import java.util.MissingResourceException; import java.util.Properties; import org.apache.openjpa.lib.conf.AbstractProductDerivation; +import org.apache.openjpa.lib.conf.Configuration; import org.apache.openjpa.lib.conf.ConfigurationProvider; import org.apache.openjpa.lib.conf.MapConfigurationProvider; import org.apache.openjpa.lib.conf.ProductDerivation; @@ -37,9 +38,15 @@ import org.apache.openjpa.lib.conf.ProductDerivation; public class ConfigurationTestProductDerivation extends AbstractProductDerivation { + public static boolean closed = false; + public int getType() { return ProductDerivation.TYPE_PRODUCT; } + + public void beforeConfigurationClose(Configuration conf) { + closed = true; + } public ConfigurationProvider loadGlobals(ClassLoader loader) throws IOException { diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/TestConfigurationImpl.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/TestConfigurationImpl.java index 5c033527e..9df26acdd 100644 --- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/TestConfigurationImpl.java +++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/TestConfigurationImpl.java @@ -234,6 +234,13 @@ public class TestConfigurationImpl extends AbstractTestCase { assertEquals("java.lang.StringBuffer", copy2.getPluginKey()); assertEquals("", copy2.getPluginKeyInstance().toString()); } + + public void testProductDerivationCloseCallback() { + // toggle the static. This will be reset by the close invocation. + ConfigurationTestProductDerivation.closed = false; + _conf.close(); + assertTrue(ConfigurationTestProductDerivation.closed); + } public static void main(String[] args) { main();