You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2015/03/03 09:20:32 UTC

isis git commit: ISIS-1064: enhance DataNucluesApplicationComponents to support new listener; implement CreateSchemaObjectFromClassMetadata listener.

Repository: isis
Updated Branches:
  refs/heads/ISIS-1064 [created] b2b2ed279


ISIS-1064: enhance DataNucluesApplicationComponents to support new listener; implement CreateSchemaObjectFromClassMetadata listener.

In addition:
- minor tidy-up of IsisJdoSupportImpl to use try-with-resources.
- some javadoc fixes elsewhere


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

Branch: refs/heads/ISIS-1064
Commit: b2b2ed27988933228f68bc20fc0500ed871c3cc9
Parents: 0ccc73e
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Mar 3 08:20:11 2015 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue Mar 3 08:20:11 2015 +0000

----------------------------------------------------------------------
 .../JavaReflectorInstallerNoDecorators.java     |   4 +-
 .../CreateSchemaObjectFromClassMetadata.java    | 164 +++++++++++++++++++
 .../DataNucleusApplicationComponents.java       |  79 +++++----
 ...ataNucleusPersistenceMechanismInstaller.java |  21 ++-
 .../datanucleus/DataNucleusPropertiesAware.java |  27 +++
 .../PersistenceManagerFactoryAware.java         |  26 +++
 .../service/support/IsisJdoSupportImpl.java     |  52 ++----
 7 files changed, 298 insertions(+), 75 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/b2b2ed27/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/JavaReflectorInstallerNoDecorators.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/JavaReflectorInstallerNoDecorators.java b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/JavaReflectorInstallerNoDecorators.java
index 2d6e8bf..443e3a9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/JavaReflectorInstallerNoDecorators.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/JavaReflectorInstallerNoDecorators.java
@@ -159,9 +159,7 @@ public class JavaReflectorInstallerNoDecorators extends InstallerAbstract implem
      * <p>
      * By default, looks up implementation from provided
      * {@link IsisConfiguration} using
-     * {@link ReflectorConstants#META_MODEL_VALIDATOR_CLASS_NAME}. If not
-     * specified, then defaults to
-     * {@value ReflectorConstants#META_MODEL_VALIDATOR_CLASS_NAME_DEFAULT}.
+     * {@link ReflectorConstants#META_MODEL_VALIDATOR_CLASS_NAME}.
      */
     protected MetaModelValidator createMetaModelValidator(final IsisConfiguration configuration) {
         final String metaModelValidatorClassName = configuration.getString(ReflectorConstants.META_MODEL_VALIDATOR_CLASS_NAME, ReflectorConstants.META_MODEL_VALIDATOR_CLASS_NAME_DEFAULT);

http://git-wip-us.apache.org/repos/asf/isis/blob/b2b2ed27/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/CreateSchemaObjectFromClassMetadata.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/CreateSchemaObjectFromClassMetadata.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/CreateSchemaObjectFromClassMetadata.java
new file mode 100644
index 0000000..e4ce6cc
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/CreateSchemaObjectFromClassMetadata.java
@@ -0,0 +1,164 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.datanucleus;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Locale;
+import java.util.Map;
+import javax.jdo.PersistenceManagerFactory;
+import com.google.common.base.Strings;
+import org.datanucleus.metadata.AbstractClassMetaData;
+import org.datanucleus.metadata.MetaDataListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, PersistenceManagerFactoryAware, DataNucleusPropertiesAware {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DataNucleusPersistenceMechanismInstaller.class);
+
+    // unused
+    protected PersistenceManagerFactory persistenceManagerFactory;
+    protected Map<String, String> properties;
+
+    protected String driverName;
+    protected String url;
+
+    @Override
+    public void loaded(final AbstractClassMetaData cmd) {
+
+        final String schemaName = cmd.getSchema();
+        if(Strings.isNullOrEmpty(schemaName)) {
+            return;
+        }
+
+        driverName = properties.get("javax.jdo.option.ConnectionDriverName");
+        url = properties.get("javax.jdo.option.ConnectionURL");
+        final String userName = properties.get("javax.jdo.option.ConnectionUserName");
+        final String password = properties.get("javax.jdo.option.ConnectionPassword");
+
+        Connection connection = null;
+        Statement statement = null;
+        try {
+            connection = DriverManager.getConnection(url, userName, password);
+            statement = connection.createStatement();
+            if(skip(cmd, statement)) {
+                return;
+            }
+            exec(cmd, statement);
+        } catch (SQLException e) {
+            LOG.warn("Unable to create schema", e);
+        } finally {
+            closeSafely(statement);
+            closeSafely(connection);
+        }
+    }
+
+    protected void closeSafely(final AutoCloseable connection) {
+        if(connection != null) {
+            try {
+                connection.close();
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+    }
+
+    //region > skip
+
+    /**
+     * Whether to skip creating this schema.
+     */
+    protected boolean skip(final AbstractClassMetaData cmd, final Statement statement) throws SQLException {
+        final String schemaName = cmd.getSchema();
+        if(Strings.isNullOrEmpty(schemaName)) {
+            return true;
+        }
+        final String sql = buildSqlToCheck(cmd);
+        try (final ResultSet rs = statement.executeQuery(sql)) {
+            rs.next();
+            final int cnt = rs.getInt(1);
+            return cnt > 0;
+        }
+    }
+
+    protected String buildSqlToCheck(final AbstractClassMetaData cmd) {
+        final String schemaName = schemaNameFor(cmd);
+        return String.format("SELECT count(*) FROM INFORMATION_SCHEMA.SCHEMATA where SCHEMA_NAME = '%s'", schemaName);
+    }
+    //endregion
+
+    //region > exec
+
+    /**
+     * Create the schema
+     */
+    protected boolean exec(final AbstractClassMetaData cmd, final Statement statement) throws SQLException {
+        final String sql = buildSqlToExec(cmd);
+        return statement.execute(sql);
+    }
+
+    protected String buildSqlToExec(final AbstractClassMetaData cmd) {
+        final String schemaName = schemaNameFor(cmd);
+        return String.format("CREATE SCHEMA \"%s\"", schemaName);
+    }
+    //endregion
+
+    /**
+     * Determine the name of the schema.
+     */
+    protected String schemaNameFor(final AbstractClassMetaData cmd) {
+        String schemaName = cmd.getSchema();
+
+        // DN uses different casing for identifiers.
+        //
+        // http://www.datanucleus.org/products/accessplatform_3_2/jdo/orm/datastore_identifiers.html
+        // http://www.datanucleus.org/products/accessplatform_4_0/jdo/orm/datastore_identifiers.html
+        //
+        // the following attempts to accommodate heuristically for the "out-of-the-box" behaviour for three common
+        // db vendors without requiring lots of complex configuration of DataNucleus
+        //
+
+        if(url.contains("postgres")) {
+            schemaName = schemaName.toLowerCase(Locale.ROOT);
+        }
+        if(url.contains("hsqldb")) {
+            schemaName = schemaName.toUpperCase(Locale.ROOT);
+        }
+        if(url.contains("sqlserver")) {
+            // unchanged
+        }
+        return schemaName;
+    }
+
+
+    // //////////////////////////////////////
+
+    public void setPersistenceManagerFactory(final PersistenceManagerFactory persistenceManagerFactory) {
+        this.persistenceManagerFactory = persistenceManagerFactory;
+    }
+
+    @Override
+    public void setDataNucleusProperties(final Map<String, String> properties) {
+        this.properties = properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/b2b2ed27/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusApplicationComponents.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusApplicationComponents.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusApplicationComponents.java
index 6ca9e5d..fe5b82e 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusApplicationComponents.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusApplicationComponents.java
@@ -21,20 +21,20 @@ package org.apache.isis.objectstore.jdo.datanucleus;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-
 import javax.jdo.JDOHelper;
 import javax.jdo.PersistenceManager;
 import javax.jdo.PersistenceManagerFactory;
-
 import com.google.common.base.Joiner;
 import com.google.common.collect.Maps;
-
 import org.datanucleus.NucleusContext;
 import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
+import org.datanucleus.metadata.MetaDataListener;
 import org.datanucleus.metadata.MetaDataManager;
 import org.datanucleus.store.StoreManager;
 import org.datanucleus.store.schema.SchemaAwareStoreManager;
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer;
@@ -72,11 +72,10 @@ public class DataNucleusApplicationComponents implements ApplicationScopedCompon
     }
 
     ///////////////////////////////////////////////////////////////////////////
-    //
-    ///////////////////////////////////////////////////////////////////////////
-    
+
     private final Set<String> persistableClassNameSet;
-    private final Map<String, String> props;
+    private final IsisConfiguration jdoObjectstoreConfig;
+    private final Map<String, String> datanucleusProps;
     
     private final IsisLifecycleListener lifecycleListener;
     private final FrameworkSynchronizer synchronizer;
@@ -85,57 +84,77 @@ public class DataNucleusApplicationComponents implements ApplicationScopedCompon
     private PersistenceManagerFactory persistenceManagerFactory;
 
     public DataNucleusApplicationComponents(
-            final Map<String, String> props, 
+            final IsisConfiguration jdoObjectstoreConfig,
+            final Map<String, String> datanucleusProps,
             final Set<String> persistableClassNameSet) {
     
-        this.props = props;
+        this.datanucleusProps = datanucleusProps;
         this.persistableClassNameSet = persistableClassNameSet;
+        this.jdoObjectstoreConfig = jdoObjectstoreConfig;
 
         this.synchronizer = new FrameworkSynchronizer();
         this.lifecycleListener = new IsisLifecycleListener(synchronizer);
 
-        init(props, persistableClassNameSet);
+        initialize();
         
         // for JRebel plugin
         instance = this;
     }
 
-    private void init(final Map<String, String> props, final Set<String> persistableClassNameSet) {
+    private void initialize() {
         final String persistableClassNames = Joiner.on(',').join(persistableClassNameSet);
         
-        props.put("datanucleus.autoStartClassNames", persistableClassNames);
-        persistenceManagerFactory = JDOHelper.getPersistenceManagerFactory(props);
+        datanucleusProps.put("datanucleus.autoStartClassNames", persistableClassNames);
+        persistenceManagerFactory = JDOHelper.getPersistenceManagerFactory(datanucleusProps);
 
-        final boolean createSchema = Boolean.parseBoolean( props.get("datanucleus.autoCreateSchema") );
+        final boolean createSchema = Boolean.parseBoolean(datanucleusProps.get("datanucleus.autoCreateSchema"));
         if(createSchema) {
-            createSchema(props, persistableClassNameSet);
+            createSchema();
         }
 
         namedQueryByName = catalogNamedQueries(persistableClassNameSet);
-
     }
     
-    public PersistenceManagerFactory getPersistenceManagerFactory() {
-        return persistenceManagerFactory;
-    }
-
-    private void createSchema(final Map<String, String> props, final Set<String> classesToBePersisted) {
+    private void createSchema() {
         final JDOPersistenceManagerFactory jdopmf = (JDOPersistenceManagerFactory)persistenceManagerFactory;
         final NucleusContext nucleusContext = jdopmf.getNucleusContext();
         final StoreManager storeManager = nucleusContext.getStoreManager();
+        final MetaDataManager metaDataManager = nucleusContext.getMetaDataManager();
+
+        registerMetadataListener(metaDataManager);
         if (storeManager instanceof SchemaAwareStoreManager) {
-            ((SchemaAwareStoreManager)storeManager).createSchema(classesToBePersisted, asProperties(props));
-		}
+            final SchemaAwareStoreManager schemaAwareStoreManager = (SchemaAwareStoreManager) storeManager;
+            schemaAwareStoreManager.createSchema(persistableClassNameSet, asProperties(datanucleusProps));
+        }
+    }
+
+    private void registerMetadataListener(final MetaDataManager metaDataManager) {
+        final MetaDataListener listener = createMetaDataListener();
+        if(listener instanceof PersistenceManagerFactoryAware) {
+            ((PersistenceManagerFactoryAware) listener).setPersistenceManagerFactory(persistenceManagerFactory);
+        }
+
+        if(listener instanceof DataNucleusPropertiesAware) {
+            ((DataNucleusPropertiesAware) listener).setDataNucleusProperties(datanucleusProps);
+        }
+        metaDataManager.registerListener(listener);
+    }
+
+    private MetaDataListener createMetaDataListener() {
+        final String classMetadataListenerClassName = jdoObjectstoreConfig.getString(
+                DataNucleusPersistenceMechanismInstaller.CLASS_METADATA_LOADED_LISTENER_KEY,
+                DataNucleusPersistenceMechanismInstaller.CLASS_METADATA_LOADED_LISTENER_DEFAULT);
+        return InstanceUtil.createInstance(classMetadataListenerClassName, MetaDataListener.class);
     }
 
 
-    private static Properties asProperties(Map<String, String> props) {
-        Properties properties = new Properties();
+    private static Properties asProperties(final Map<String, String> props) {
+        final Properties properties = new Properties();
         properties.putAll(props);
         return properties;
     }
 
-    private static Map<String, JdoNamedQuery> catalogNamedQueries(Set<String> persistableClassNames) {
+    private static Map<String, JdoNamedQuery> catalogNamedQueries(final Set<String> persistableClassNames) {
         final Map<String, JdoNamedQuery> namedQueryByName = Maps.newHashMap();
         for (final String persistableClassName: persistableClassNames) {
             final ObjectSpecification spec = IsisContext.getSpecificationLoader().loadSpecification(persistableClassName);
@@ -150,6 +169,10 @@ public class DataNucleusApplicationComponents implements ApplicationScopedCompon
         return namedQueryByName;
     }
 
+    public PersistenceManagerFactory getPersistenceManagerFactory() {
+        return persistenceManagerFactory;
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     //
     ///////////////////////////////////////////////////////////////////////////
@@ -177,13 +200,13 @@ public class DataNucleusApplicationComponents implements ApplicationScopedCompon
     ///////////////////////////////////////////////////////////////////////////
     
     public PersistenceManager createPersistenceManager() {
-        PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
+        final PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
         
         persistenceManager.addInstanceLifecycleListener(lifecycleListener, (Class[])null);
         return persistenceManager;
     }
 
-    public JdoNamedQuery getNamedQuery(String queryName) {
+    public JdoNamedQuery getNamedQuery(final String queryName) {
         return namedQueryByName.get(queryName);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/b2b2ed27/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
index e1d711c..cf18228 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
@@ -61,7 +61,7 @@ import org.apache.isis.objectstore.jdo.service.RegisterEntities;
  * </ul>
  * 
  * <p>
- * With respect to configuration, all properties under {@value #ISIS_CONFIG_PREFIX} prefix are passed 
+ * With respect to configuration, all properties under {@value #DATANUCLEUS_CONFIG_PREFIX} prefix are passed
  * through verbatim to the DataNucleus runtime. For example:
  * <table>
  * <tr><th>Isis Property</th><th>DataNucleus Property</th></tr>
@@ -75,7 +75,11 @@ public class DataNucleusPersistenceMechanismInstaller extends PersistenceMechani
 
     public static final String NAME = "datanucleus";
 
-    private static final String ISIS_CONFIG_PREFIX = "isis.persistor.datanucleus.impl";
+    public static final String CLASS_METADATA_LOADED_LISTENER_KEY = "classMetadataLoadedListener";
+    static final String CLASS_METADATA_LOADED_LISTENER_DEFAULT = CreateSchemaObjectFromClassMetadata.class.getName();
+
+    private static final String JDO_OBJECTSTORE_CONFIG_PREFIX = "isis.persistor.datanucleus";  // specific to the JDO objectstore
+    private static final String DATANUCLEUS_CONFIG_PREFIX = "isis.persistor.datanucleus.impl"; // reserved for datanucleus' own config props
 
     public DataNucleusPersistenceMechanismInstaller() {
         super(NAME);
@@ -100,16 +104,15 @@ public class DataNucleusPersistenceMechanismInstaller extends PersistenceMechani
 
         if (applicationComponents == null || applicationComponents.isStale()) {
 
-            // this is, perhaps doing more work than necessary...
-            // maybe retain the applicationComponents and just tell it to discard its PMF?
-            // (doubt will make much different in terms of the amount of time to process, though)
+            final IsisConfiguration jdoObjectstoreConfig = configuration.createSubset(JDO_OBJECTSTORE_CONFIG_PREFIX);
 
-            final IsisConfiguration dataNucleusConfig = configuration.createSubset(ISIS_CONFIG_PREFIX);
-            final Map<String, String> props = dataNucleusConfig.asMap();
-            addDataNucleusPropertiesIfRequired(props);
+            final IsisConfiguration dataNucleusConfig = configuration.createSubset(DATANUCLEUS_CONFIG_PREFIX);
+            final Map<String, String> datanucleusProps = dataNucleusConfig.asMap();
+            addDataNucleusPropertiesIfRequired(datanucleusProps);
 
             final Set<String> classesToBePersisted = catalogClassesToBePersisted(configuration, getSpecificationLoader().allSpecifications());
-            applicationComponents = new DataNucleusApplicationComponents(props, classesToBePersisted);
+
+            applicationComponents = new DataNucleusApplicationComponents(jdoObjectstoreConfig, datanucleusProps, classesToBePersisted);
         }
 
         return applicationComponents;

http://git-wip-us.apache.org/repos/asf/isis/blob/b2b2ed27/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPropertiesAware.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPropertiesAware.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPropertiesAware.java
new file mode 100644
index 0000000..4aa9c2f
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPropertiesAware.java
@@ -0,0 +1,27 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.datanucleus;
+
+import java.util.Map;
+import java.util.Properties;
+
+public interface DataNucleusPropertiesAware {
+
+    public void setDataNucleusProperties(final Map<String, String> properties);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/b2b2ed27/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/PersistenceManagerFactoryAware.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/PersistenceManagerFactoryAware.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/PersistenceManagerFactoryAware.java
new file mode 100644
index 0000000..887af87
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/PersistenceManagerFactoryAware.java
@@ -0,0 +1,26 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.datanucleus;
+
+import javax.jdo.PersistenceManagerFactory;
+
+public interface PersistenceManagerFactoryAware {
+
+    public void setPersistenceManagerFactory(final PersistenceManagerFactory persistenceManagerFactory);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/b2b2ed27/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java
index c748e15..be9dd9e 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java
@@ -59,16 +59,16 @@ public class IsisJdoSupportImpl implements IsisJdoSupport {
     
     @Programmatic
     @Override
-    public <T> T refresh(T domainObject) {
-        DataNucleusObjectStore objectStore = getObjectStore();
-        ObjectAdapter adapter = getAdapterManager().adapterFor(domainObject);
+    public <T> T refresh(final T domainObject) {
+        final DataNucleusObjectStore objectStore = getObjectStore();
+        final ObjectAdapter adapter = getAdapterManager().adapterFor(domainObject);
         objectStore.refreshRoot(adapter);
         return domainObject;
     }
 
     @Programmatic
     @Override
-    public void ensureLoaded(Collection<?> domainObjects) {
+    public void ensureLoaded(final Collection<?> domainObjects) {
         getObjectStore().getPersistenceManager().retrieveAll(domainObjects);
     }
 
@@ -76,14 +76,14 @@ public class IsisJdoSupportImpl implements IsisJdoSupport {
 
     @Programmatic
     @Override
-    public List<Map<String, Object>> executeSql(String sql) {
+    public List<Map<String, Object>> executeSql(final String sql) {
         final JDOConnection dataStoreConnection = getJdoPersistenceManager().getDataStoreConnection();
         try {
             final Object connectionObj = dataStoreConnection.getNativeConnection();
             if(!(connectionObj instanceof java.sql.Connection)) {
                 return null;
             } 
-            java.sql.Connection connection = (java.sql.Connection) connectionObj;
+            final java.sql.Connection connection = (java.sql.Connection) connectionObj;
             return executeSql(connection, sql);
         } finally {
             dataStoreConnection.close();
@@ -92,30 +92,28 @@ public class IsisJdoSupportImpl implements IsisJdoSupport {
 
     @Programmatic
     @Override
-    public Integer executeUpdate(String sql) {
+    public Integer executeUpdate(final String sql) {
         final JDOConnection dataStoreConnection = getJdoPersistenceManager().getDataStoreConnection();
         try {
             final Object connectionObj = dataStoreConnection.getNativeConnection();
             if(!(connectionObj instanceof java.sql.Connection)) {
                 return null;
             } 
-            java.sql.Connection connection = (java.sql.Connection) connectionObj;
+            final java.sql.Connection connection = (java.sql.Connection) connectionObj;
             return executeUpdate(connection, sql);
         } finally {
             dataStoreConnection.close();
         }
     }
 
-    private static List<Map<String, Object>> executeSql(java.sql.Connection connection, String sql) {
+    private static List<Map<String, Object>> executeSql(final java.sql.Connection connection, final String sql) {
         final List<Map<String,Object>> rows = Lists.newArrayList();
 
-        Statement statement = null;
-        try {
-            statement = connection.createStatement();
+        try(Statement statement = connection.createStatement()) {
             final ResultSet rs = statement.executeQuery(sql);
             final ResultSetMetaData rsmd = rs.getMetaData();
             while(rs.next()) {
-                Map<String,Object> row = Maps.newLinkedHashMap(); 
+                final Map<String,Object> row = Maps.newLinkedHashMap();
                 final int columnCount = rsmd.getColumnCount();
                 for(int i=0; i<columnCount; i++) {
                     final Object val = rs.getObject(i+1);
@@ -124,45 +122,29 @@ public class IsisJdoSupportImpl implements IsisJdoSupport {
                 rows.add(row);
             }
             
-        } catch (SQLException ex) {
+        } catch (final SQLException ex) {
             throw new ObjectPersistenceException("Failed to executeSql: " + sql, ex);
-        } finally {
-            closeSafely(statement);
         }
 
         return rows;
     }
 
-    private static int executeUpdate(java.sql.Connection connection, String sql) {
+    private static int executeUpdate(final java.sql.Connection connection, final String sql) {
         
-        Statement statement = null;
-        try {
-            statement = connection.createStatement();
+        try(Statement statement = connection.createStatement()){
             return statement.executeUpdate(sql);
             
-        } catch (SQLException ex) {
+        } catch (final SQLException ex) {
             throw new ObjectPersistenceException("Failed to executeSql: " + sql, ex);
-        } finally {
-            closeSafely(statement);
         }
     }
 
-    private static void closeSafely(Statement statement) {
-        if(statement != null) {
-            try {
-                statement.close();
-            } catch (SQLException e) {
-                // ignore
-            }
-        }
-    }
-    
     // //////////////////////////////////////
 
     @Programmatic
     @Override
-    public void deleteAll(Class<?>... pcClasses) {
-        for (Class<?> pcClass : pcClasses) {
+    public void deleteAll(final Class<?>... pcClasses) {
+        for (final Class<?> pcClass : pcClasses) {
             final Extent<?> extent = getJdoPersistenceManager().getExtent(pcClass);
             final List<Object> instances = Lists.newArrayList(extent.iterator());