CAY-2026 Java 7

* Using AutoCloseable where possible
* Fixing closeable resource management throughout the code


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

Branch: refs/heads/master
Commit: 26d8434d9d79e2e9756c3ec158da9386a8bfa817
Parents: cc9ccc3
Author: aadamchik <[email protected]>
Authored: Sat Sep 12 08:35:09 2015 +0300
Committer: aadamchik <[email protected]>
Committed: Sat Sep 12 11:23:04 2015 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/test/jdbc/DBHelper.java  |  545 +++---
 .../cayenne/test/jdbc/ResultSetTemplate.java    |   55 +-
 .../org/apache/cayenne/test/jdbc/SQLReader.java |    6 +-
 .../cayenne/test/jdbc/UpdateTemplate.java       |   91 +-
 .../cayenne/test/resource/ResourceUtil.java     |   26 +-
 .../cayenne/crypto/key/JceksKeySource.java      |  201 ++-
 .../crypto/transformer/bytes/GzipEncryptor.java |   53 +-
 .../transformer/bytes/GzipDecryptorTest.java    |   57 +-
 .../server/DBCPDataSourceFactory.java           |    9 +-
 .../cayenne/project/FileProjectSaver.java       |  584 +++----
 .../project/upgrade/BaseUpgradeHandler.java     |  304 ++--
 .../upgrade/DataSourceInfoLoader_3_0_0_1.java   |  405 ++---
 ...XMLDataChannelDescriptorLoader_V3_0_0_1.java |   14 +-
 .../upgrade/v6/XMLDataMapLoader_V3_0_0_1.java   |   47 +-
 .../java/org/apache/cayenne/BaseContext.java    | 1266 +++++++-------
 .../org/apache/cayenne/ResultBatchIterator.java |    7 +-
 .../java/org/apache/cayenne/ResultIterator.java |    3 +-
 .../cayenne/access/DataDomainQueryAction.java   |    4 +-
 .../org/apache/cayenne/access/DataPort.java     |   10 +-
 .../org/apache/cayenne/access/DbGenerator.java  |   11 +-
 .../access/DbGeneratorPostprocessor.java        |   62 +-
 .../org/apache/cayenne/access/DbLoader.java     | 1498 ++++++++---------
 .../cayenne/access/IncrementalFaultList.java    | 1549 +++++++++---------
 .../access/dbsync/CreateIfNoSchemaStrategy.java |  126 +-
 .../cayenne/access/dbsync/SchemaAnalyzer.java   |  352 ++--
 .../dbsync/ThrowOnPartialSchemaStrategy.java    |  154 +-
 .../apache/cayenne/access/jdbc/BatchAction.java |  434 +++--
 .../cayenne/access/jdbc/ProcedureAction.java    |  394 +++--
 .../loader/DbAttributesPerSchemaLoader.java     |  168 +-
 .../cayenne/access/loader/DbTableLoader.java    |  325 ++--
 .../cayenne/access/types/ByteArrayType.java     |  347 ++--
 .../apache/cayenne/access/types/CharType.java   |  282 ++--
 .../access/types/SerializableTypeFactory.java   |  177 +-
 .../XMLDataChannelDescriptorLoader.java         |   11 +-
 .../server/DefaultDbAdapterFactory.java         |  178 +-
 .../cayenne/datasource/PoolAwareConnection.java |   13 +-
 .../org/apache/cayenne/dba/JdbcPkGenerator.java |  729 ++++-----
 .../org/apache/cayenne/dba/TypesHandler.java    |  206 +--
 .../org/apache/cayenne/dba/TypesMapping.java    |  979 ++++++-----
 .../apache/cayenne/dba/db2/DB2PkGenerator.java  |  306 ++--
 .../cayenne/dba/db2/DB2ProcedureAction.java     |   80 +-
 .../cayenne/dba/derby/DerbyPkGenerator.java     |  109 +-
 .../apache/cayenne/dba/h2/H2PkGenerator.java    |  143 +-
 .../cayenne/dba/ingres/IngresPkGenerator.java   |  124 +-
 .../cayenne/dba/mysql/MySQLPkGenerator.java     |  312 ++--
 .../cayenne/dba/mysql/MySQLProcedureAction.java |  209 ++-
 .../apache/cayenne/dba/mysql/MySQLSniffer.java  |   80 +-
 .../dba/openbase/OpenBasePkGenerator.java       |  489 +++---
 .../dba/oracle/Oracle8LOBBatchAction.java       |  406 +++--
 .../dba/oracle/Oracle8LOBBatchQueryWrapper.java |  324 ++--
 .../cayenne/dba/oracle/OraclePkGenerator.java   |  379 ++---
 .../dba/oracle/OracleProcedureAction.java       |   98 +-
 .../dba/oracle/OracleSQLTemplateAction.java     |    3 +
 .../dba/postgres/PostgresPkGenerator.java       |  157 +-
 .../dba/sqlserver/SQLServerBatchAction.java     |  139 +-
 .../dba/sqlserver/SQLServerProcedureAction.java |  296 ++--
 .../cayenne/dba/sybase/SybasePkGenerator.java   |  366 ++---
 .../apache/cayenne/merge/AbstractToDbToken.java |  196 +--
 .../java/org/apache/cayenne/merge/DbMerger.java |  724 ++++----
 .../main/java/org/apache/cayenne/util/Util.java |   23 +-
 .../apache/cayenne/access/DataContextIT.java    |   21 +-
 .../access/DataContextSQLTemplateIT.java        |  937 +++++------
 .../cayenne/access/MockOperationObserver.java   |    4 +-
 .../access/dbsync/SchemaUpdateStrategyBase.java |   45 +-
 .../access/jdbc/JDBCResultIteratorTest.java     |   61 +-
 .../access/jdbc/SQLTemplateActionIT.java        |  596 ++++---
 .../dba/sqlserver/SQLServerSnifferIT.java       |   59 +-
 .../org/apache/cayenne/merge/MergeCase.java     |   26 +-
 .../cayenne/query/ObjectSelect_RunIT.java       |  119 +-
 .../org/apache/cayenne/query/SQLSelectIT.java   |  191 +--
 .../org/apache/cayenne/query/SelectQueryIT.java |   10 +-
 .../resource/FilesystemResourceLocatorTest.java |  146 +-
 .../org/apache/cayenne/unit/HSQLProcedures.java |   60 +-
 .../cayenne/unit/SybaseUnitDbAdapter.java       |  253 ++-
 .../cayenne/unit/di/server/SchemaBuilder.java   |  643 ++++----
 .../java/org/apache/cayenne/util/UtilTest.java  |  530 +++---
 .../cayenne/gen/ClassGenerationAction.java      | 1111 +++++++------
 .../cayenne/tools/dbimport/DbImportAction.java  |  450 ++---
 ...eGeneratorTaskCrossMapRelationshipsTest.java |  254 ++-
 .../cayenne/tools/CayenneGeneratorTaskTest.java |  631 ++++---
 .../cayenne/tools/DbImporterTaskTest.java       |   32 +-
 .../tools/CayenneGeneratorIntegrationTest.java  |   11 +-
 .../modeler/action/ImportDataMapAction.java     |  178 +-
 .../modeler/dialog/db/DataSourceWizard.java     |  373 ++---
 .../dialog/pref/DataSourcePreferences.java      |    8 +-
 .../modeler/graph/action/SaveAsImageAction.java |  120 +-
 .../apache/cayenne/wocompat/EOModelHelper.java  |  817 +++++----
 .../cayenne/wocompat/EOModelProcessor.java      | 1434 ++++++++--------
 .../wocompat/PropertyListSerialization.java     |  460 +++---
 .../cayenne/wocompat/EOModelHelperTest.java     |  171 +-
 90 files changed, 12678 insertions(+), 13718 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/DBHelper.java
----------------------------------------------------------------------
diff --git 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/DBHelper.java
 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/DBHelper.java
index 4989221..faeefee 100644
--- 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/DBHelper.java
+++ 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/DBHelper.java
@@ -36,340 +36,335 @@ import javax.sql.DataSource;
  */
 public class DBHelper {
 
-    protected DataSource dataSource;
-
-    public DBHelper(DataSource dataSource) {
-        this.dataSource = dataSource;
-    }
-
-    /**
-     * Quotes a SQL identifier as appropriate for the given DB. This
-     * implementation returns the identifier unchanged, while subclasses can
-     * implement a custom quoting strategy.
-     */
-    protected String quote(String sqlIdentifier) {
-        return sqlIdentifier;
-    }
-
-    /**
-     * Selects a single row.
-     */
-    public Object[] select(String table, final String[] columns) throws 
SQLException {
-
-        if (columns.length == 0) {
-            throw new IllegalArgumentException("No columns");
-        }
-
-        StringBuilder sql = new StringBuilder("select ");
-        sql.append(quote(columns[0]));
-        for (int i = 1; i < columns.length; i++) {
-            sql.append(", ").append(quote(columns[i]));
-        }
-        sql.append(" from ").append(quote(table));
-
-        return new RowTemplate<Object[]>(this) {
-
-            @Override
-            Object[] readRow(ResultSet rs, String sql) throws SQLException {
-
-                Object[] result = new Object[columns.length];
-                for (int i = 1; i <= result.length; i++) {
-                    result[i - 1] = rs.getObject(i);
-                }
-
-                return result;
-            }
-        }.execute(sql.toString());
-    }
-
-    public List<Object[]> selectAll(String table, final String[] columns) 
throws SQLException {
-        if (columns.length == 0) {
-            throw new IllegalArgumentException("No columns");
-        }
-
-        StringBuilder sql = new StringBuilder("select ");
-        sql.append(quote(columns[0]));
-        for (int i = 1; i < columns.length; i++) {
-            sql.append(", ").append(quote(columns[i]));
-        }
-        sql.append(" from ").append(quote(table));
-
-        return new ResultSetTemplate<List<Object[]>>(this) {
-            @Override
-            List<Object[]> readResultSet(ResultSet rs, String sql) throws 
SQLException {
-
-                List<Object[]> result = new ArrayList<Object[]>();
-                while (rs.next()) {
-
-                    Object[] row = new Object[columns.length];
-                    for (int i = 1; i <= row.length; i++) {
-                        row[i - 1] = rs.getObject(i);
-                    }
-
-                    result.add(row);
-                }
-
-                return result;
-            }
-        }.execute(sql.toString());
-    }
-
-    /**
-     * Inserts a single row. Columns types can be null and will be determined
-     * from ParameterMetaData in this case. The later scenario will not work if
-     * values contains nulls and the DB is Oracle.
-     */
-    public void insert(String table, String[] columns, Object[] values, int[] 
columnTypes) throws SQLException {
-
-        if (columns.length != values.length) {
-            throw new IllegalArgumentException("Columns and values arrays have 
different sizes: " + columns.length
-                    + " and " + values.length);
-        }
-
-        if (columns.length == 0) {
-            throw new IllegalArgumentException("No columns");
-        }
-
-        StringBuilder sql = new StringBuilder("INSERT INTO ");
-        sql.append(quote(table)).append(" (").append(quote(columns[0]));
-        for (int i = 1; i < columns.length; i++) {
-            sql.append(", ").append(quote(columns[i]));
-        }
-
-        sql.append(") VALUES (?");
-        for (int i = 1; i < values.length; i++) {
-            sql.append(", ?");
-        }
-        sql.append(")");
-
-        Connection c = getConnection();
-        try {
-
-            String sqlString = sql.toString();
-            UtilityLogger.log(sqlString);
-            PreparedStatement st = c.prepareStatement(sqlString);
-            ParameterMetaData parameters = null;
-            try {
-                for (int i = 0; i < values.length; i++) {
-
-                    if (values[i] == null) {
+       protected DataSource dataSource;
+
+       public DBHelper(DataSource dataSource) {
+               this.dataSource = dataSource;
+       }
+
+       /**
+        * Quotes a SQL identifier as appropriate for the given DB. This
+        * implementation returns the identifier unchanged, while subclasses can
+        * implement a custom quoting strategy.
+        */
+       protected String quote(String sqlIdentifier) {
+               return sqlIdentifier;
+       }
+
+       /**
+        * Selects a single row.
+        */
+       public Object[] select(String table, final String[] columns) throws 
SQLException {
+
+               if (columns.length == 0) {
+                       throw new IllegalArgumentException("No columns");
+               }
+
+               StringBuilder sql = new StringBuilder("select ");
+               sql.append(quote(columns[0]));
+               for (int i = 1; i < columns.length; i++) {
+                       sql.append(", ").append(quote(columns[i]));
+               }
+               sql.append(" from ").append(quote(table));
+
+               return new RowTemplate<Object[]>(this) {
+
+                       @Override
+                       Object[] readRow(ResultSet rs, String sql) throws 
SQLException {
+
+                               Object[] result = new Object[columns.length];
+                               for (int i = 1; i <= result.length; i++) {
+                                       result[i - 1] = rs.getObject(i);
+                               }
+
+                               return result;
+                       }
+               }.execute(sql.toString());
+       }
+
+       public List<Object[]> selectAll(String table, final String[] columns) 
throws SQLException {
+               if (columns.length == 0) {
+                       throw new IllegalArgumentException("No columns");
+               }
+
+               StringBuilder sql = new StringBuilder("select ");
+               sql.append(quote(columns[0]));
+               for (int i = 1; i < columns.length; i++) {
+                       sql.append(", ").append(quote(columns[i]));
+               }
+               sql.append(" from ").append(quote(table));
+
+               return new ResultSetTemplate<List<Object[]>>(this) {
+                       @Override
+                       List<Object[]> readResultSet(ResultSet rs, String sql) 
throws SQLException {
+
+                               List<Object[]> result = new 
ArrayList<Object[]>();
+                               while (rs.next()) {
+
+                                       Object[] row = new 
Object[columns.length];
+                                       for (int i = 1; i <= row.length; i++) {
+                                               row[i - 1] = rs.getObject(i);
+                                       }
+
+                                       result.add(row);
+                               }
+
+                               return result;
+                       }
+               }.execute(sql.toString());
+       }
+
+       /**
+        * Inserts a single row. Columns types can be null and will be 
determined
+        * from ParameterMetaData in this case. The later scenario will not 
work if
+        * values contains nulls and the DB is Oracle.
+        */
+       public void insert(String table, String[] columns, Object[] values, 
int[] columnTypes) throws SQLException {
+
+               if (columns.length != values.length) {
+                       throw new IllegalArgumentException("Columns and values 
arrays have different sizes: " + columns.length
+                                       + " and " + values.length);
+               }
+
+               if (columns.length == 0) {
+                       throw new IllegalArgumentException("No columns");
+               }
+
+               StringBuilder sql = new StringBuilder("INSERT INTO ");
+               sql.append(quote(table)).append(" (").append(quote(columns[0]));
+               for (int i = 1; i < columns.length; i++) {
+                       sql.append(", ").append(quote(columns[i]));
+               }
 
-                        int type;
+               sql.append(") VALUES (?");
+               for (int i = 1; i < values.length; i++) {
+                       sql.append(", ?");
+               }
+               sql.append(")");
 
-                        if (columnTypes == null) {
-
-                            // check for the right NULL type
-                            if (parameters == null) {
-                                parameters = st.getParameterMetaData();
-                            }
+               try (Connection c = getConnection();) {
 
-                            type = parameters.getParameterType(i + 1);
-                        } else {
-                            type = columnTypes[i];
-                        }
+                       String sqlString = sql.toString();
+                       UtilityLogger.log(sqlString);
 
-                        st.setNull(i + 1, type);
-                    } else {
-                        st.setObject(i + 1, values[i]);
-                    }
-                }
+                       ParameterMetaData parameters = null;
+                       try (PreparedStatement st = 
c.prepareStatement(sqlString);) {
+                               for (int i = 0; i < values.length; i++) {
 
-                st.executeUpdate();
-            } finally {
-                st.close();
-            }
-            c.commit();
-        } finally {
-            c.close();
-        }
+                                       if (values[i] == null) {
 
-    }
+                                               int type;
 
-    public int deleteAll(String tableName) throws SQLException {
-        return delete(tableName).execute();
-    }
+                                               if (columnTypes == null) {
 
-    public UpdateBuilder update(String tableName) throws SQLException {
-        return new UpdateBuilder(this, tableName);
-    }
+                                                       // check for the right 
NULL type
+                                                       if (parameters == null) 
{
+                                                               parameters = 
st.getParameterMetaData();
+                                                       }
 
-    public DeleteBuilder delete(String tableName) {
-        return new DeleteBuilder(this, tableName);
-    }
+                                                       type = 
parameters.getParameterType(i + 1);
+                                               } else {
+                                                       type = columnTypes[i];
+                                               }
 
-    public int getRowCount(String table) throws SQLException {
-        String sql = "select count(*) from " + quote(table);
+                                               st.setNull(i + 1, type);
+                                       } else {
+                                               st.setObject(i + 1, values[i]);
+                                       }
+                               }
 
-        return new RowTemplate<Integer>(this) {
+                               st.executeUpdate();
+                       }
+                       c.commit();
+               }
 
-            @Override
-            Integer readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getInt(1);
-            }
+       }
 
-        }.execute(sql);
-    }
+       public int deleteAll(String tableName) throws SQLException {
+               return delete(tableName).execute();
+       }
 
-    public String getString(String table, String column) throws SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+       public UpdateBuilder update(String tableName) throws SQLException {
+               return new UpdateBuilder(this, tableName);
+       }
 
-        return new RowTemplate<String>(this) {
+       public DeleteBuilder delete(String tableName) {
+               return new DeleteBuilder(this, tableName);
+       }
 
-            @Override
-            String readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getString(1);
-            }
+       public int getRowCount(String table) throws SQLException {
+               String sql = "select count(*) from " + quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<Integer>(this) {
 
-    public Object getObject(String table, String column) throws SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+                       @Override
+                       Integer readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getInt(1);
+                       }
 
-        return new RowTemplate<Object>(this) {
+               }.execute(sql);
+       }
 
-            @Override
-            Object readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getObject(1);
-            }
+       public String getString(String table, String column) throws 
SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<String>(this) {
 
-    public byte getByte(String table, String column) throws SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+                       @Override
+                       String readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getString(1);
+                       }
 
-        return new RowTemplate<Byte>(this) {
+               }.execute(sql);
+       }
 
-            @Override
-            Byte readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getByte(1);
-            }
+       public Object getObject(String table, String column) throws 
SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<Object>(this) {
 
-    public byte[] getBytes(String table, String column) throws SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+                       @Override
+                       Object readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getObject(1);
+                       }
 
-        return new RowTemplate<byte[]>(this) {
+               }.execute(sql);
+       }
 
-            @Override
-            byte[] readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getBytes(1);
-            }
+       public byte getByte(String table, String column) throws SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<Byte>(this) {
 
-    public int getInt(String table, String column) throws SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+                       @Override
+                       Byte readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getByte(1);
+                       }
 
-        return new RowTemplate<Integer>(this) {
+               }.execute(sql);
+       }
 
-            @Override
-            Integer readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getInt(1);
-            }
+       public byte[] getBytes(String table, String column) throws SQLException 
{
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<byte[]>(this) {
 
-    public long getLong(String table, String column) throws SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+                       @Override
+                       byte[] readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getBytes(1);
+                       }
 
-        return new RowTemplate<Long>(this) {
+               }.execute(sql);
+       }
 
-            @Override
-            Long readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getLong(1);
-            }
+       public int getInt(String table, String column) throws SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<Integer>(this) {
 
-    public double getDouble(String table, String column) throws SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+                       @Override
+                       Integer readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getInt(1);
+                       }
 
-        return new RowTemplate<Double>(this) {
+               }.execute(sql);
+       }
 
-            @Override
-            Double readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getDouble(1);
-            }
+       public long getLong(String table, String column) throws SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<Long>(this) {
 
-    public boolean getBoolean(String table, String column) throws SQLException 
{
-        final String sql = "select " + quote(column) + " from " + quote(table);
+                       @Override
+                       Long readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getLong(1);
+                       }
 
-        return new RowTemplate<Boolean>(this) {
+               }.execute(sql);
+       }
 
-            @Override
-            Boolean readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getBoolean(1);
-            }
+       public double getDouble(String table, String column) throws 
SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<Double>(this) {
 
-    public java.util.Date getUtilDate(String table, String column) throws 
SQLException {
-        Timestamp ts = getTimestamp(table, column);
-        return ts != null ? new java.util.Date(ts.getTime()) : null;
-    }
+                       @Override
+                       Double readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getDouble(1);
+                       }
 
-    public java.sql.Date getSqlDate(String table, String column) throws 
SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+               }.execute(sql);
+       }
 
-        return new RowTemplate<java.sql.Date>(this) {
+       public boolean getBoolean(String table, String column) throws 
SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-            @Override
-            java.sql.Date readRow(ResultSet rs, String sql) throws 
SQLException {
-                return rs.getDate(1);
-            }
+               return new RowTemplate<Boolean>(this) {
 
-        }.execute(sql);
-    }
+                       @Override
+                       Boolean readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getBoolean(1);
+                       }
 
-    public Time getTime(String table, String column) throws SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+               }.execute(sql);
+       }
 
-        return new RowTemplate<Time>(this) {
+       public java.util.Date getUtilDate(String table, String column) throws 
SQLException {
+               Timestamp ts = getTimestamp(table, column);
+               return ts != null ? new java.util.Date(ts.getTime()) : null;
+       }
 
-            @Override
-            Time readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getTime(1);
-            }
+       public java.sql.Date getSqlDate(String table, String column) throws 
SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<java.sql.Date>(this) {
 
-    public Timestamp getTimestamp(String table, String column) throws 
SQLException {
-        final String sql = "select " + quote(column) + " from " + quote(table);
+                       @Override
+                       java.sql.Date readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getDate(1);
+                       }
 
-        return new RowTemplate<Timestamp>(this) {
+               }.execute(sql);
+       }
 
-            @Override
-            Timestamp readRow(ResultSet rs, String sql) throws SQLException {
-                return rs.getTimestamp(1);
-            }
+       public Time getTime(String table, String column) throws SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
 
-        }.execute(sql);
-    }
+               return new RowTemplate<Time>(this) {
 
-    public Connection getConnection() throws SQLException {
-        Connection connection = dataSource.getConnection();
+                       @Override
+                       Time readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getTime(1);
+                       }
 
-        try {
-            connection.setAutoCommit(false);
-        } catch (SQLException e) {
+               }.execute(sql);
+       }
 
-            try {
-                connection.close();
-            } catch (SQLException ignored) {
-            }
-        }
-        return connection;
-    }
+       public Timestamp getTimestamp(String table, String column) throws 
SQLException {
+               final String sql = "select " + quote(column) + " from " + 
quote(table);
+
+               return new RowTemplate<Timestamp>(this) {
+
+                       @Override
+                       Timestamp readRow(ResultSet rs, String sql) throws 
SQLException {
+                               return rs.getTimestamp(1);
+                       }
+
+               }.execute(sql);
+       }
+
+       public Connection getConnection() throws SQLException {
+               Connection connection = dataSource.getConnection();
+
+               try {
+                       connection.setAutoCommit(false);
+               } catch (SQLException e) {
+
+                       try {
+                               connection.close();
+                       } catch (SQLException ignored) {
+                       }
+               }
+               return connection;
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/ResultSetTemplate.java
----------------------------------------------------------------------
diff --git 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/ResultSetTemplate.java
 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/ResultSetTemplate.java
index 6b7fbfc..123ac7f 100644
--- 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/ResultSetTemplate.java
+++ 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/ResultSetTemplate.java
@@ -25,37 +25,26 @@ import java.sql.SQLException;
 
 abstract class ResultSetTemplate<T> {
 
-    DBHelper parent;
-
-    public ResultSetTemplate(DBHelper parent) {
-        this.parent = parent;
-    }
-
-    abstract T readResultSet(ResultSet rs, String sql) throws SQLException;
-
-    T execute(String sql) throws SQLException {
-        UtilityLogger.log(sql);
-        Connection c = parent.getConnection();
-        try {
-
-            PreparedStatement st = c.prepareStatement(sql);
-
-            try {
-                ResultSet rs = st.executeQuery();
-                try {
-
-                    return readResultSet(rs, sql);
-                }
-                finally {
-                    rs.close();
-                }
-            }
-            finally {
-                st.close();
-            }
-        }
-        finally {
-            c.close();
-        }
-    }
+       DBHelper parent;
+
+       public ResultSetTemplate(DBHelper parent) {
+               this.parent = parent;
+       }
+
+       abstract T readResultSet(ResultSet rs, String sql) throws SQLException;
+
+       T execute(String sql) throws SQLException {
+               UtilityLogger.log(sql);
+
+               try (Connection c = parent.getConnection();) {
+
+                       try (PreparedStatement st = c.prepareStatement(sql);) {
+
+                               try (ResultSet rs = st.executeQuery();) {
+
+                                       return readResultSet(rs, sql);
+                               }
+                       }
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/SQLReader.java
----------------------------------------------------------------------
diff --git 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/SQLReader.java
 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/SQLReader.java
index 12afef2..e602fba 100644
--- 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/SQLReader.java
+++ 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/SQLReader.java
@@ -45,8 +45,7 @@ public class SQLReader {
 
                Collection<String> statements = new ArrayList<String>();
 
-               BufferedReader reader = new BufferedReader(new 
InputStreamReader(sqlSource.openStream(), "UTF-8"));
-               try {
+               try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(sqlSource.openStream(), "UTF-8"));) {
 
                        String line;
                        StringBuilder statement = new StringBuilder();
@@ -60,9 +59,6 @@ public class SQLReader {
                        if (statement.length() > 0) {
                                statements.add(statement.toString());
                        }
-
-               } finally {
-                       reader.close();
                }
 
                return statements;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/UpdateTemplate.java
----------------------------------------------------------------------
diff --git 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/UpdateTemplate.java
 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/UpdateTemplate.java
index d56cdff..45afda8 100644
--- 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/UpdateTemplate.java
+++ 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/jdbc/UpdateTemplate.java
@@ -25,67 +25,52 @@ import java.util.Collection;
 
 class UpdateTemplate {
 
-    DBHelper parent;
+       DBHelper parent;
 
-    public UpdateTemplate(DBHelper parent) {
-        this.parent = parent;
-    }
+       public UpdateTemplate(DBHelper parent) {
+               this.parent = parent;
+       }
 
-    protected void bindParameters(
-            PreparedStatement statement,
-            Collection<Object> bindings,
-            Collection<Integer> bindingTypes) throws SQLException {
+       protected void bindParameters(PreparedStatement statement, 
Collection<Object> bindings,
+                       Collection<Integer> bindingTypes) throws SQLException {
 
-        if (bindings != null && !bindings.isEmpty()) {
+               if (bindings != null && !bindings.isEmpty()) {
 
-            Object[] values = bindings.toArray();
-            Integer[] types = bindingTypes.toArray(new 
Integer[bindingTypes.size()]);
+                       Object[] values = bindings.toArray();
+                       Integer[] types = bindingTypes.toArray(new 
Integer[bindingTypes.size()]);
 
-            for (int i = 0; i < values.length; i++) {
+                       for (int i = 0; i < values.length; i++) {
 
-                if (values[i] == null) {
-                    if (types[i] != SQLBuilder.NO_TYPE) {
-                        statement.setNull(i + 1, types[i]);
-                    }
-                    else {
-                        throw new IllegalStateException(
-                                "No type information for null value at index " 
+ i);
-                    }
-                }
-                else {
-                    if (types[i] != SQLBuilder.NO_TYPE) {
-                        statement.setObject(i + 1, values[i], types[i]);
-                    }
-                    else {
-                        statement.setObject(i + 1, values[i]);
-                    }
-                }
-            }
-        }
-    }
+                               if (values[i] == null) {
+                                       if (types[i] != SQLBuilder.NO_TYPE) {
+                                               statement.setNull(i + 1, 
types[i]);
+                                       } else {
+                                               throw new 
IllegalStateException("No type information for null value at index " + i);
+                                       }
+                               } else {
+                                       if (types[i] != SQLBuilder.NO_TYPE) {
+                                               statement.setObject(i + 1, 
values[i], types[i]);
+                                       } else {
+                                               statement.setObject(i + 1, 
values[i]);
+                                       }
+                               }
+                       }
+               }
+       }
 
-    int execute(String sql, Collection<Object> bindings, Collection<Integer> 
bindingTypes)
-            throws SQLException {
-        UtilityLogger.log(sql);
-        Connection c = parent.getConnection();
-        try {
+       int execute(String sql, Collection<Object> bindings, 
Collection<Integer> bindingTypes) throws SQLException {
+               UtilityLogger.log(sql);
 
-            PreparedStatement st = c.prepareStatement(sql);
+               try (Connection c = parent.getConnection();) {
 
-            int count;
-            try {
-                bindParameters(st, bindings, bindingTypes);
-                count = st.executeUpdate();
-            }
-            finally {
-                st.close();
-            }
+                       int count;
+                       try (PreparedStatement st = c.prepareStatement(sql);) {
+                               bindParameters(st, bindings, bindingTypes);
+                               count = st.executeUpdate();
+                       }
 
-            c.commit();
-            return count;
-        }
-        finally {
-            c.close();
-        }
-    }
+                       c.commit();
+                       return count;
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/resource/ResourceUtil.java
----------------------------------------------------------------------
diff --git 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/resource/ResourceUtil.java
 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/resource/ResourceUtil.java
index f989273..0b5c20a 100644
--- 
a/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/resource/ResourceUtil.java
+++ 
b/build-tools/cayenne-test-utilities/src/main/java/org/apache/cayenne/test/resource/ResourceUtil.java
@@ -82,30 +82,16 @@ public class ResourceUtil {
        }
 
        public static boolean copyResourceToFile(URL from, File to) {
-               BufferedInputStream urlin = null;
-               BufferedOutputStream fout = null;
-               try {
-                       int bufSize = 8 * 1024;
-                       urlin = new 
BufferedInputStream(from.openConnection().getInputStream(), bufSize);
-                       fout = new BufferedOutputStream(new 
FileOutputStream(to), bufSize);
-                       copyPipe(urlin, fout, bufSize);
+               int bufSize = 8 * 1024;
+               try (BufferedInputStream urlin = new 
BufferedInputStream(from.openConnection().getInputStream(), bufSize);) {
+
+                       try (BufferedOutputStream fout = new 
BufferedOutputStream(new FileOutputStream(to), bufSize);) {
+                               copyPipe(urlin, fout, bufSize);
+                       }
                } catch (IOException ioex) {
                        return false;
                } catch (SecurityException sx) {
                        return false;
-               } finally {
-                       if (urlin != null) {
-                               try {
-                                       urlin.close();
-                               } catch (IOException cioex) {
-                               }
-                       }
-                       if (fout != null) {
-                               try {
-                                       fout.close();
-                               } catch (IOException cioex) {
-                               }
-                       }
                }
                return true;
        }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java
----------------------------------------------------------------------
diff --git 
a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java
 
b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java
index 5a4c10e..38781af 100644
--- 
a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java
+++ 
b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java
@@ -43,106 +43,103 @@ import org.apache.cayenne.di.Inject;
  */
 public class JceksKeySource implements KeySource {
 
-    // this is the only standard keystore type that supports storing secret 
keys
-    private static final String JCEKS_KEYSTORE_TYPE = "jceks";
-    private static final Key NULL_KEY = new Key() {
-
-        private static final long serialVersionUID = 4755682444381893880L;
-
-        @Override
-        public String getFormat() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public byte[] getEncoded() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public String getAlgorithm() {
-            throw new UnsupportedOperationException();
-        }
-    };
-
-    private KeyStore keyStore;
-    private char[] keyPassword;
-    private String defaultKeyAlias;
-
-    // caching the keys may not be a good idea for security reasons, but
-    // re-reading the key from KeyStore for every select row creates a huge
-    // bottleneck... And considering we are caching keystore password, it
-    // probably doesn't make things that much worse
-    private ConcurrentMap<String, Key> keyCache;
-
-    public JceksKeySource(@Inject(CryptoConstants.PROPERTIES_MAP) Map<String, 
String> properties,
-            @Inject(CryptoConstants.CREDENTIALS_MAP) Map<String, char[]> 
credentials) {
-
-        String keyStoreUrl = properties.get(CryptoConstants.KEYSTORE_URL);
-        if (keyStoreUrl == null) {
-            throw new CayenneCryptoException("KeyStore URL is not set. 
Property name: " + CryptoConstants.KEYSTORE_URL);
-        }
-
-        this.keyPassword = credentials.get(CryptoConstants.KEY_PASSWORD);
-        // NULL password is valid, though not secure .. so no NULL validation
-
-        try {
-            this.keyStore = createKeyStore(keyStoreUrl);
-        } catch (Exception e) {
-            throw new CayenneCryptoException("Error loading keystore at " + 
keyStoreUrl, e);
-        }
-
-        this.defaultKeyAlias = 
properties.get(CryptoConstants.ENCRYPTION_KEY_ALIAS);
-        if (defaultKeyAlias == null) {
-            throw new CayenneCryptoException("Default key alias is not set. 
Property name: "
-                    + CryptoConstants.ENCRYPTION_KEY_ALIAS);
-        }
-
-        this.keyCache = new ConcurrentHashMap<String, Key>();
-    }
-
-    private KeyStore createKeyStore(String keyStoreUrl) throws 
KeyStoreException, IOException,
-            NoSuchAlgorithmException, CertificateException {
-
-        KeyStore keyStore = KeyStore.getInstance(JCEKS_KEYSTORE_TYPE);
-
-        URL url = new URL(keyStoreUrl);
-        InputStream in = url.openStream();
-
-        try {
-            keyStore.load(in, null);
-        } finally {
-            in.close();
-        }
-
-        return keyStore;
-    }
-
-    @Override
-    public Key getKey(String alias) {
-
-        Key key = keyCache.get(alias);
-        if (key == null) {
-
-            Key newKey = createKey(alias);
-            Key oldKey = keyCache.putIfAbsent(alias, newKey);
-            key = oldKey != null ? oldKey : newKey;
-        }
-
-        return key == NULL_KEY ? null : key;
-    }
-
-    protected Key createKey(String alias) {
-        try {
-            Key key = keyStore.getKey(alias, keyPassword);
-            return key != null ? key : NULL_KEY;
-        } catch (Exception e) {
-            throw new CayenneCryptoException("Error accessing key for alias: " 
+ alias, e);
-        }
-    }
-
-    @Override
-    public String getDefaultKeyAlias() {
-        return defaultKeyAlias;
-    }
+       // this is the only standard keystore type that supports storing secret 
keys
+       private static final String JCEKS_KEYSTORE_TYPE = "jceks";
+       private static final Key NULL_KEY = new Key() {
+
+               private static final long serialVersionUID = 
4755682444381893880L;
+
+               @Override
+               public String getFormat() {
+                       throw new UnsupportedOperationException();
+               }
+
+               @Override
+               public byte[] getEncoded() {
+                       throw new UnsupportedOperationException();
+               }
+
+               @Override
+               public String getAlgorithm() {
+                       throw new UnsupportedOperationException();
+               }
+       };
+
+       private KeyStore keyStore;
+       private char[] keyPassword;
+       private String defaultKeyAlias;
+
+       // caching the keys may not be a good idea for security reasons, but
+       // re-reading the key from KeyStore for every select row creates a huge
+       // bottleneck... And considering we are caching keystore password, it
+       // probably doesn't make things that much worse
+       private ConcurrentMap<String, Key> keyCache;
+
+       public JceksKeySource(@Inject(CryptoConstants.PROPERTIES_MAP) 
Map<String, String> properties,
+                       @Inject(CryptoConstants.CREDENTIALS_MAP) Map<String, 
char[]> credentials) {
+
+               String keyStoreUrl = 
properties.get(CryptoConstants.KEYSTORE_URL);
+               if (keyStoreUrl == null) {
+                       throw new CayenneCryptoException("KeyStore URL is not 
set. Property name: " + CryptoConstants.KEYSTORE_URL);
+               }
+
+               this.keyPassword = 
credentials.get(CryptoConstants.KEY_PASSWORD);
+               // NULL password is valid, though not secure .. so no NULL 
validation
+
+               try {
+                       this.keyStore = createKeyStore(keyStoreUrl);
+               } catch (Exception e) {
+                       throw new CayenneCryptoException("Error loading 
keystore at " + keyStoreUrl, e);
+               }
+
+               this.defaultKeyAlias = 
properties.get(CryptoConstants.ENCRYPTION_KEY_ALIAS);
+               if (defaultKeyAlias == null) {
+                       throw new CayenneCryptoException("Default key alias is 
not set. Property name: "
+                                       + CryptoConstants.ENCRYPTION_KEY_ALIAS);
+               }
+
+               this.keyCache = new ConcurrentHashMap<String, Key>();
+       }
+
+       private KeyStore createKeyStore(String keyStoreUrl) throws 
KeyStoreException, IOException,
+                       NoSuchAlgorithmException, CertificateException {
+
+               KeyStore keyStore = KeyStore.getInstance(JCEKS_KEYSTORE_TYPE);
+
+               URL url = new URL(keyStoreUrl);
+
+               try (InputStream in = url.openStream();) {
+                       keyStore.load(in, null);
+               }
+
+               return keyStore;
+       }
+
+       @Override
+       public Key getKey(String alias) {
+
+               Key key = keyCache.get(alias);
+               if (key == null) {
+
+                       Key newKey = createKey(alias);
+                       Key oldKey = keyCache.putIfAbsent(alias, newKey);
+                       key = oldKey != null ? oldKey : newKey;
+               }
+
+               return key == NULL_KEY ? null : key;
+       }
+
+       protected Key createKey(String alias) {
+               try {
+                       Key key = keyStore.getKey(alias, keyPassword);
+                       return key != null ? key : NULL_KEY;
+               } catch (Exception e) {
+                       throw new CayenneCryptoException("Error accessing key 
for alias: " + alias, e);
+               }
+       }
+
+       @Override
+       public String getDefaultKeyAlias() {
+               return defaultKeyAlias;
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/GzipEncryptor.java
----------------------------------------------------------------------
diff --git 
a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/GzipEncryptor.java
 
b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/GzipEncryptor.java
index 1936c52..d966312 100644
--- 
a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/GzipEncryptor.java
+++ 
b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/GzipEncryptor.java
@@ -29,40 +29,39 @@ import org.apache.cayenne.crypto.CayenneCryptoException;
  */
 class GzipEncryptor implements BytesEncryptor {
 
-    static final int GZIP_THRESHOLD = 150;
+       static final int GZIP_THRESHOLD = 150;
 
-    private BytesEncryptor delegate;
+       private BytesEncryptor delegate;
 
-    public GzipEncryptor(BytesEncryptor delegate) {
-        this.delegate = delegate;
-    }
+       public GzipEncryptor(BytesEncryptor delegate) {
+               this.delegate = delegate;
+       }
 
-    @Override
-    public byte[] encrypt(byte[] input, int outputOffset, byte[] flags) {
+       @Override
+       public byte[] encrypt(byte[] input, int outputOffset, byte[] flags) {
 
-        boolean compressed = input.length >= GZIP_THRESHOLD;
+               boolean compressed = input.length >= GZIP_THRESHOLD;
 
-        if (compressed) {
-            try {
-                input = gzip(input);
-            } catch (IOException e) {
-                // really not expecting an error here...
-                throw new CayenneCryptoException("Error compressing input", e);
-            }
-        }
+               if (compressed) {
+                       try {
+                               input = gzip(input);
+                       } catch (IOException e) {
+                               // really not expecting an error here...
+                               throw new CayenneCryptoException("Error 
compressing input", e);
+                       }
+               }
 
-        flags[0] = Header.setCompressed(flags[0], compressed);
-        return delegate.encrypt(input, outputOffset, flags);
-    }
+               flags[0] = Header.setCompressed(flags[0], compressed);
+               return delegate.encrypt(input, outputOffset, flags);
+       }
 
-    static byte[] gzip(byte[] input) throws IOException {
-        ByteArrayOutputStream zipBytes = new 
ByteArrayOutputStream(input.length);
-        GZIPOutputStream out = new GZIPOutputStream(zipBytes);
+       static byte[] gzip(byte[] input) throws IOException {
+               ByteArrayOutputStream zipBytes = new 
ByteArrayOutputStream(input.length);
+               try (GZIPOutputStream out = new GZIPOutputStream(zipBytes);) {
+                       out.write(input, 0, input.length);
+               }
 
-        out.write(input, 0, input.length);
-        out.close();
-
-        return zipBytes.toByteArray();
-    }
+               return zipBytes.toByteArray();
+       }
 
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/GzipDecryptorTest.java
----------------------------------------------------------------------
diff --git 
a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/GzipDecryptorTest.java
 
b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/GzipDecryptorTest.java
index 4a1c3fe..84dafd7 100644
--- 
a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/GzipDecryptorTest.java
+++ 
b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/GzipDecryptorTest.java
@@ -30,45 +30,40 @@ import org.junit.Test;
 
 public class GzipDecryptorTest {
 
-    @Test
-    public void testGunzip() throws IOException {
+       @Test
+       public void testGunzip() throws IOException {
 
-        byte[] input1 = 
CryptoUnitUtils.hexToBytes("1f8b0800000000000000f348cdc9c957f0409000a91a078c11000000");
-        byte[] output1 = GzipDecryptor.gunzip(input1);
-        byte[] expectedOutput1 = "Hello Hello Hello".getBytes("UTF8");
+               byte[] input1 = 
CryptoUnitUtils.hexToBytes("1f8b0800000000000000f348cdc9c957f0409000a91a078c11000000");
+               byte[] output1 = GzipDecryptor.gunzip(input1);
+               byte[] expectedOutput1 = "Hello Hello Hello".getBytes("UTF8");
 
-        assertArrayEquals(expectedOutput1, output1);
-    }
+               assertArrayEquals(expectedOutput1, output1);
+       }
 
-    @Test
-    public void testGunzip_Large() throws IOException {
+       @Test
+       public void testGunzip_Large() throws IOException {
 
-        byte[] input1 = readResource("plain.txt.gz");
-        byte[] output1 = GzipDecryptor.gunzip(input1);
-        byte[] expectedOutput1 = readResource("plain.txt");
+               byte[] input1 = readResource("plain.txt.gz");
+               byte[] output1 = GzipDecryptor.gunzip(input1);
+               byte[] expectedOutput1 = readResource("plain.txt");
 
-        assertArrayEquals(expectedOutput1, output1);
-    }
+               assertArrayEquals(expectedOutput1, output1);
+       }
 
-    private byte[] readResource(String name) throws IOException {
+       private byte[] readResource(String name) throws IOException {
 
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+               ByteArrayOutputStream out = new ByteArrayOutputStream();
 
-        InputStream in = getClass().getResourceAsStream(name);
-        assertNotNull(in);
+               try (InputStream in = getClass().getResourceAsStream(name);) {
 
-        try {
+                       assertNotNull(in);
+                       int read;
+                       byte[] buffer = new byte[1024];
+                       while ((read = in.read(buffer)) > 0) {
+                               out.write(buffer, 0, read);
+                       }
+               }
 
-            int read;
-            byte[] buffer = new byte[1024];
-            while ((read = in.read(buffer)) > 0) {
-                out.write(buffer, 0, read);
-            }
-
-        } finally {
-            in.close();
-        }
-
-        return out.toByteArray();
-    }
+               return out.toByteArray();
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/cayenne-dbcp2/src/main/java/org/apache/cayenne/configuration/server/DBCPDataSourceFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbcp2/src/main/java/org/apache/cayenne/configuration/server/DBCPDataSourceFactory.java
 
b/cayenne-dbcp2/src/main/java/org/apache/cayenne/configuration/server/DBCPDataSourceFactory.java
index ecdc59d..69c5bdd 100644
--- 
a/cayenne-dbcp2/src/main/java/org/apache/cayenne/configuration/server/DBCPDataSourceFactory.java
+++ 
b/cayenne-dbcp2/src/main/java/org/apache/cayenne/configuration/server/DBCPDataSourceFactory.java
@@ -71,14 +71,9 @@ public class DBCPDataSourceFactory implements 
DataSourceFactory {
 
        private Properties getProperties(Resource dbcp2Configuration) throws 
IOException {
                Properties properties = new Properties();
-               InputStream in = dbcp2Configuration.getURL().openStream();
-               try {
+
+               try (InputStream in = 
dbcp2Configuration.getURL().openStream();) {
                        properties.load(in);
-               } finally {
-                       try {
-                               in.close();
-                       } catch (IOException e) {
-                       }
                }
 
                return properties;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
----------------------------------------------------------------------
diff --git 
a/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
 
b/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
index b403ed5..98249d4 100644
--- 
a/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
+++ 
b/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
@@ -46,318 +46,278 @@ import java.util.Collection;
  */
 public class FileProjectSaver implements ProjectSaver {
 
-    @Inject
-    protected ConfigurationNameMapper nameMapper;
-
-    protected ConfigurationNodeVisitor<Resource> resourceGetter;
-    protected ConfigurationNodeVisitor<Collection<ConfigurationNode>> 
saveableNodesGetter;
-    protected String fileEncoding;
-
-    public FileProjectSaver() {
-        resourceGetter = new ConfigurationSourceGetter();
-        saveableNodesGetter = new SaveableNodesGetter();
-
-        // this is not configurable yet... probably doesn't have to be
-        fileEncoding = "UTF-8";
-    }
-
-    public String getSupportedVersion() {
-        return "7";
-    }
-
-    public void save(Project project) {
-        save(project, project.getConfigurationResource(), true);
-    }
-
-    public void saveAs(Project project, Resource baseDirectory) {
-        if (baseDirectory == null) {
-            throw new NullPointerException("Null 'baseDirectory'");
-        }
-        save(project, baseDirectory, false);
-    }
-
-    void save(Project project, Resource baseResource, boolean 
deleteOldResources) {
-        Collection<ConfigurationNode> nodes = 
project.getRootNode().acceptVisitor(
-                saveableNodesGetter);
-        Collection<SaveUnit> units = new ArrayList<SaveUnit>(nodes.size());
-
-        for (ConfigurationNode node : nodes) {
-            units.add(createSaveUnit(node, baseResource));
-        }
-
-        checkAccess(units);
-
-        try {
-            saveToTempFiles(units);
-            saveCommit(units);
-        }
-        finally {
-            clearTempFiles(units);
-        }
-
-        try {
-            if (deleteOldResources) {
-                clearRenamedFiles(units);
-
-                Collection<URL> unusedResources = project.getUnusedResources();
-                for (SaveUnit unit : units) {
-                    unusedResources.remove(unit.sourceConfiguration.getURL());
-                }
-                deleteUnusedFiles(unusedResources);
-            }
-        }
-        catch (IOException ex) {
-            throw new CayenneRuntimeException(ex);
-        }
-        
-       // I guess we should reset projects state regardless of the value of
+       @Inject
+       protected ConfigurationNameMapper nameMapper;
+
+       protected ConfigurationNodeVisitor<Resource> resourceGetter;
+       protected ConfigurationNodeVisitor<Collection<ConfigurationNode>> 
saveableNodesGetter;
+       protected String fileEncoding;
+
+       public FileProjectSaver() {
+               resourceGetter = new ConfigurationSourceGetter();
+               saveableNodesGetter = new SaveableNodesGetter();
+
+               // this is not configurable yet... probably doesn't have to be
+               fileEncoding = "UTF-8";
+       }
+
+       public String getSupportedVersion() {
+               return "7";
+       }
+
+       public void save(Project project) {
+               save(project, project.getConfigurationResource(), true);
+       }
+
+       public void saveAs(Project project, Resource baseDirectory) {
+               if (baseDirectory == null) {
+                       throw new NullPointerException("Null 'baseDirectory'");
+               }
+               save(project, baseDirectory, false);
+       }
+
+       void save(Project project, Resource baseResource, boolean 
deleteOldResources) {
+               Collection<ConfigurationNode> nodes = 
project.getRootNode().acceptVisitor(saveableNodesGetter);
+               Collection<SaveUnit> units = new 
ArrayList<SaveUnit>(nodes.size());
+
+               for (ConfigurationNode node : nodes) {
+                       units.add(createSaveUnit(node, baseResource));
+               }
+
+               checkAccess(units);
+
+               try {
+                       saveToTempFiles(units);
+                       saveCommit(units);
+               } finally {
+                       clearTempFiles(units);
+               }
+
+               try {
+                       if (deleteOldResources) {
+                               clearRenamedFiles(units);
+
+                               Collection<URL> unusedResources = 
project.getUnusedResources();
+                               for (SaveUnit unit : units) {
+                                       
unusedResources.remove(unit.sourceConfiguration.getURL());
+                               }
+                               deleteUnusedFiles(unusedResources);
+                       }
+               } catch (IOException ex) {
+                       throw new CayenneRuntimeException(ex);
+               }
+
+               // I guess we should reset projects state regardless of the 
value of
                // 'deleteOldResources'
                project.getUnusedResources().clear();
-    }
-
-    SaveUnit createSaveUnit(ConfigurationNode node, Resource baseResource) {
-
-        SaveUnit unit = new SaveUnit();
-        unit.node = node;
-        unit.sourceConfiguration = node.acceptVisitor(resourceGetter);
-
-        String targetLocation = nameMapper.configurationLocation(node);
-        Resource targetResource = 
baseResource.getRelativeResource(targetLocation);
-
-        if (unit.sourceConfiguration == null) {
-            unit.sourceConfiguration = targetResource;
-        }
-
-        // attempt to convert targetResource to a File... if that fails,
-        // FileProjectSaver is not appropriate for handling a given project..
-
-        URL targetUrl = targetResource.getURL();
-
-        try {
-            unit.targetFile = Util.toFile(targetUrl);
-        }
-        catch (IllegalArgumentException e) {
-            throw new CayenneRuntimeException(
-                    "Can't save configuration to the following location: '%s'. 
"
-                            + "Is this a valid file location?. (%s)",
-                    e,
-                    targetUrl,
-                    e.getMessage());
-        }
-
-        return unit;
-    }
-
-    void checkAccess(Collection<SaveUnit> units) {
-        for (SaveUnit unit : units) {
-
-            File targetFile = unit.targetFile;
-
-            File parent = targetFile.getParentFile();
-            if (!parent.exists()) {
-                if (!parent.mkdirs()) {
-                    throw new CayenneRuntimeException(
-                            "Error creating directory tree for '%s'",
-                            parent.getAbsolutePath());
-                }
-            }
-
-            if (targetFile.isDirectory()) {
-                throw new CayenneRuntimeException(
-                        "Target file '%s' is a directory",
-                        targetFile.getAbsolutePath());
-            }
-
-            if (targetFile.exists() && !targetFile.canWrite()) {
-                throw new CayenneRuntimeException("Can't write to file '%s'", 
targetFile
-                        .getAbsolutePath());
-            }
-
-        }
-    }
-
-    void saveToTempFiles(Collection<SaveUnit> units) {
-
-        for (SaveUnit unit : units) {
-
-            String name = unit.targetFile.getName();
-            if (name == null || name.length() < 3) {
-                name = "cayenne-project";
-            }
-
-            File parent = unit.targetFile.getParentFile();
-
-            try {
-                unit.targetTempFile = File.createTempFile(name, null, parent);
-            }
-            catch (IOException e) {
-                throw new CayenneRuntimeException("Error creating temp file 
(%s)", e, e
-                        .getMessage());
-            }
-
-            if (unit.targetTempFile.exists()) {
-                unit.targetTempFile.delete();
-            }
-
-            PrintWriter printWriter;
-            try {
-                printWriter = new PrintWriter(new OutputStreamWriter(
-                        new FileOutputStream(unit.targetTempFile),
-                        fileEncoding));
-            }
-            catch (UnsupportedEncodingException e) {
-                throw new CayenneRuntimeException(
-                        "Unsupported encoding '%s' (%s)",
-                        e,
-                        fileEncoding,
-                        e.getMessage());
-            }
-            catch (FileNotFoundException e) {
-                throw new CayenneRuntimeException(
-                        "File not found '%s' (%s)",
-                        e,
-                        unit.targetTempFile.getAbsolutePath(),
-                        e.getMessage());
-            }
-
-            try {
-                saveToTempFile(unit, printWriter);
-            }
-            finally {
-                printWriter.close();
-            }
-        }
-    }
-
-    void saveToTempFile(SaveUnit unit, PrintWriter printWriter) {
-        unit.node
-                .acceptVisitor(new ConfigurationSaver(printWriter, 
getSupportedVersion()));
-    }
-
-    void saveCommit(Collection<SaveUnit> units) {
-
-        for (SaveUnit unit : units) {
-
-            File targetFile = unit.targetFile;
-
-            if (targetFile.exists()) {
-                if (!targetFile.delete()) {
-                    throw new CayenneRuntimeException(
-                            "Unable to remove old master file '%s'",
-                            targetFile.getAbsolutePath());
-                }
-            }
-
-            File tempFile = unit.targetTempFile;
-            if (!tempFile.renameTo(targetFile)) {
-                throw new CayenneRuntimeException("Unable to move '%s' to 
'%s'", tempFile
-                        .getAbsolutePath(), targetFile.getAbsolutePath());
-            }
-
-            unit.targetTempFile = null;
-            try {
-                unit.node.acceptVisitor(new ConfigurationSourceSetter(new 
URLResource(
-                        targetFile.toURL())));
-            }
-            catch (MalformedURLException e) {
-                throw new CayenneRuntimeException(
-                        "Malformed URL for file '%s'",
-                        e,
-                        targetFile.getAbsolutePath());
-            }
-        }
-    }
-
-    private void clearTempFiles(Collection<SaveUnit> units) {
-        for (SaveUnit unit : units) {
-
-            if (unit.targetTempFile != null && unit.targetTempFile.exists()) {
-                unit.targetTempFile.delete();
-                unit.targetTempFile = null;
-            }
-        }
-    }
-
-    private void clearRenamedFiles(Collection<SaveUnit> units) throws 
IOException {
-        for (SaveUnit unit : units) {
-
-            if (unit.sourceConfiguration == null) {
-                continue;
-            }
-
-            URL sourceUrl = unit.sourceConfiguration.getURL();
-            File sourceFile;
-            try {
-                sourceFile = Util.toFile(sourceUrl);
-            }
-            catch (IllegalArgumentException e) {
-                // ignore non-file configurations...
-                continue;
-            }
-
-            if (!sourceFile.exists()) {
-                continue;
-            }
-
-            // compare against ALL unit target files, not just the current 
unit... if the
-            // target matches, skip this file
-            boolean isTarget = false;
-            for (SaveUnit xunit : units) {
-                if (isFilesEquals(sourceFile, xunit.targetFile)) {
-                    isTarget = true;
-                    break;
-                }
-            }
-
-            if (!isTarget) {
-                if (!sourceFile.delete()) {
-                    throw new CayenneRuntimeException("Could not delete file 
'%s'", sourceFile.getCanonicalPath());
-                }
-            }
-        }
-    }
-
-    private boolean isFilesEquals(File firstFile, File secondFile) throws 
IOException {
-        boolean isFirstFileExists = firstFile.exists();
-        boolean isSecondFileExists = secondFile.exists();
-
-        String firstFilePath = firstFile.getCanonicalPath();
-        String secondFilePath = secondFile.getCanonicalPath();
-
-        return isFirstFileExists && isSecondFileExists && 
firstFilePath.equals(secondFilePath);
-    }
-
-    private void deleteUnusedFiles(Collection<URL> unusedResources) throws 
IOException {
-        for (URL unusedResource : unusedResources) {
-
-            File unusedFile;
-            try {
-                unusedFile = Util.toFile(unusedResource);
-            }
-            catch (IllegalArgumentException e) {
-                // ignore non-file configurations...
-                continue;
-            }
-
-            if (!unusedFile.exists()) {
-                continue;
-            }
-
-            if (!unusedFile.delete()) {
-                throw new CayenneRuntimeException("Could not delete file 
'%s'", unusedFile.getCanonicalPath());
-            }
-
-        }
-    }
-
-    class SaveUnit {
-
-        private ConfigurationNode node;
-
-        // source can be an abstract resource, but target is always a file...
-        private Resource sourceConfiguration;
-        private File targetFile;
-        private File targetTempFile;
-
-    }
+       }
+
+       SaveUnit createSaveUnit(ConfigurationNode node, Resource baseResource) {
+
+               SaveUnit unit = new SaveUnit();
+               unit.node = node;
+               unit.sourceConfiguration = node.acceptVisitor(resourceGetter);
+
+               String targetLocation = nameMapper.configurationLocation(node);
+               Resource targetResource = 
baseResource.getRelativeResource(targetLocation);
+
+               if (unit.sourceConfiguration == null) {
+                       unit.sourceConfiguration = targetResource;
+               }
+
+               // attempt to convert targetResource to a File... if that fails,
+               // FileProjectSaver is not appropriate for handling a given 
project..
+
+               URL targetUrl = targetResource.getURL();
+
+               try {
+                       unit.targetFile = Util.toFile(targetUrl);
+               } catch (IllegalArgumentException e) {
+                       throw new CayenneRuntimeException("Can't save 
configuration to the following location: '%s'. "
+                                       + "Is this a valid file location?. 
(%s)", e, targetUrl, e.getMessage());
+               }
+
+               return unit;
+       }
+
+       void checkAccess(Collection<SaveUnit> units) {
+               for (SaveUnit unit : units) {
+
+                       File targetFile = unit.targetFile;
+
+                       File parent = targetFile.getParentFile();
+                       if (!parent.exists()) {
+                               if (!parent.mkdirs()) {
+                                       throw new 
CayenneRuntimeException("Error creating directory tree for '%s'",
+                                                       
parent.getAbsolutePath());
+                               }
+                       }
+
+                       if (targetFile.isDirectory()) {
+                               throw new CayenneRuntimeException("Target file 
'%s' is a directory", targetFile.getAbsolutePath());
+                       }
+
+                       if (targetFile.exists() && !targetFile.canWrite()) {
+                               throw new CayenneRuntimeException("Can't write 
to file '%s'", targetFile.getAbsolutePath());
+                       }
+
+               }
+       }
+
+       void saveToTempFiles(Collection<SaveUnit> units) {
+
+               for (SaveUnit unit : units) {
+
+                       String name = unit.targetFile.getName();
+                       if (name == null || name.length() < 3) {
+                               name = "cayenne-project";
+                       }
+
+                       File parent = unit.targetFile.getParentFile();
+
+                       try {
+                               unit.targetTempFile = File.createTempFile(name, 
null, parent);
+                       } catch (IOException e) {
+                               throw new CayenneRuntimeException("Error 
creating temp file (%s)", e, e.getMessage());
+                       }
+
+                       if (unit.targetTempFile.exists()) {
+                               unit.targetTempFile.delete();
+                       }
+
+                       try (PrintWriter printWriter = new PrintWriter(new 
OutputStreamWriter(new FileOutputStream(
+                                       unit.targetTempFile), fileEncoding));) {
+                               saveToTempFile(unit, printWriter);
+                       } catch (UnsupportedEncodingException e) {
+                               throw new CayenneRuntimeException("Unsupported 
encoding '%s' (%s)", e, fileEncoding, e.getMessage());
+                       } catch (FileNotFoundException e) {
+                               throw new CayenneRuntimeException("File not 
found '%s' (%s)", e, unit.targetTempFile.getAbsolutePath(),
+                                               e.getMessage());
+                       }
+               }
+       }
+
+       void saveToTempFile(SaveUnit unit, PrintWriter printWriter) {
+               unit.node.acceptVisitor(new ConfigurationSaver(printWriter, 
getSupportedVersion()));
+       }
+
+       void saveCommit(Collection<SaveUnit> units) {
+
+               for (SaveUnit unit : units) {
+
+                       File targetFile = unit.targetFile;
+
+                       if (targetFile.exists()) {
+                               if (!targetFile.delete()) {
+                                       throw new 
CayenneRuntimeException("Unable to remove old master file '%s'",
+                                                       
targetFile.getAbsolutePath());
+                               }
+                       }
+
+                       File tempFile = unit.targetTempFile;
+                       if (!tempFile.renameTo(targetFile)) {
+                               throw new CayenneRuntimeException("Unable to 
move '%s' to '%s'", tempFile.getAbsolutePath(),
+                                               targetFile.getAbsolutePath());
+                       }
+
+                       unit.targetTempFile = null;
+                       try {
+                               unit.node.acceptVisitor(new 
ConfigurationSourceSetter(new URLResource(targetFile.toURL())));
+                       } catch (MalformedURLException e) {
+                               throw new CayenneRuntimeException("Malformed 
URL for file '%s'", e, targetFile.getAbsolutePath());
+                       }
+               }
+       }
+
+       private void clearTempFiles(Collection<SaveUnit> units) {
+               for (SaveUnit unit : units) {
+
+                       if (unit.targetTempFile != null && 
unit.targetTempFile.exists()) {
+                               unit.targetTempFile.delete();
+                               unit.targetTempFile = null;
+                       }
+               }
+       }
+
+       private void clearRenamedFiles(Collection<SaveUnit> units) throws 
IOException {
+               for (SaveUnit unit : units) {
+
+                       if (unit.sourceConfiguration == null) {
+                               continue;
+                       }
+
+                       URL sourceUrl = unit.sourceConfiguration.getURL();
+                       File sourceFile;
+                       try {
+                               sourceFile = Util.toFile(sourceUrl);
+                       } catch (IllegalArgumentException e) {
+                               // ignore non-file configurations...
+                               continue;
+                       }
+
+                       if (!sourceFile.exists()) {
+                               continue;
+                       }
+
+                       // compare against ALL unit target files, not just the 
current
+                       // unit... if the
+                       // target matches, skip this file
+                       boolean isTarget = false;
+                       for (SaveUnit xunit : units) {
+                               if (isFilesEquals(sourceFile, 
xunit.targetFile)) {
+                                       isTarget = true;
+                                       break;
+                               }
+                       }
+
+                       if (!isTarget) {
+                               if (!sourceFile.delete()) {
+                                       throw new 
CayenneRuntimeException("Could not delete file '%s'", 
sourceFile.getCanonicalPath());
+                               }
+                       }
+               }
+       }
+
+       private boolean isFilesEquals(File firstFile, File secondFile) throws 
IOException {
+               boolean isFirstFileExists = firstFile.exists();
+               boolean isSecondFileExists = secondFile.exists();
+
+               String firstFilePath = firstFile.getCanonicalPath();
+               String secondFilePath = secondFile.getCanonicalPath();
+
+               return isFirstFileExists && isSecondFileExists && 
firstFilePath.equals(secondFilePath);
+       }
+
+       private void deleteUnusedFiles(Collection<URL> unusedResources) throws 
IOException {
+               for (URL unusedResource : unusedResources) {
+
+                       File unusedFile;
+                       try {
+                               unusedFile = Util.toFile(unusedResource);
+                       } catch (IllegalArgumentException e) {
+                               // ignore non-file configurations...
+                               continue;
+                       }
+
+                       if (!unusedFile.exists()) {
+                               continue;
+                       }
+
+                       if (!unusedFile.delete()) {
+                               throw new CayenneRuntimeException("Could not 
delete file '%s'", unusedFile.getCanonicalPath());
+                       }
+
+               }
+       }
+
+       class SaveUnit {
+
+               private ConfigurationNode node;
+
+               // source can be an abstract resource, but target is always a 
file...
+               private Resource sourceConfiguration;
+               private File targetFile;
+               private File targetTempFile;
+
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/BaseUpgradeHandler.java
----------------------------------------------------------------------
diff --git 
a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/BaseUpgradeHandler.java
 
b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/BaseUpgradeHandler.java
index a14e7b0..a22b7d7 100644
--- 
a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/BaseUpgradeHandler.java
+++ 
b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/BaseUpgradeHandler.java
@@ -44,161 +44,151 @@ import org.xml.sax.helpers.DefaultHandler;
 // the code here seems like version-agnostic
 public abstract class BaseUpgradeHandler implements UpgradeHandler {
 
-    static final String UNKNOWN_VERSION = "0";
-
-    protected Resource projectSource;
-    protected UpgradeMetaData metaData;
-
-    public BaseUpgradeHandler(Resource projectSource) {
-
-        if (projectSource == null) {
-            throw new NullPointerException("Null project source");
-        }
-
-        this.projectSource = projectSource;
-    }
-
-    /**
-     * Creates a single common EntityResolver for all project DataMaps, setting
-     * it as a namespace for all of them. This is needed for resolving 
cross-map
-     * relationships.
-     */
-    protected void attachToNamespace(DataChannelDescriptor channelDescriptor) {
-        EntityResolver entityResolver = new 
EntityResolver(channelDescriptor.getDataMaps());
-
-        for (DataMap map : entityResolver.getDataMaps()) {
-            map.setNamespace(entityResolver);
-        }
-    }
-
-    @Override
-    public Resource getProjectSource() {
-        return projectSource;
-    }
-
-    @Override
-    public UpgradeMetaData getUpgradeMetaData() {
-        // no attempts at thread-safety... shouldn't be needed for upgrades
-        if (metaData == null) {
-            metaData = loadMetaData();
-        }
-
-        return metaData;
-    }
-
-    @Override
-    public Resource performUpgrade() throws ConfigurationException {
-        UpgradeMetaData metaData = getUpgradeMetaData();
-        switch (metaData.getUpgradeType()) {
-        case DOWNGRADE_NEEDED:
-            throw new ConfigurationException("Downgrade can not be performed");
-        case INTERMEDIATE_UPGRADE_NEEDED:
-            throw new ConfigurationException("Upgrade can not be performed - 
intermediate version upgrade needed");
-        case UPGRADE_NEEDED:
-            return doPerformUpgrade(metaData);
-        default:
-            return getProjectSource();
-        }
-    }
-
-    /**
-     * Does the actual project upgrade, assuming the caller already verified
-     * that the upgrade is possible.
-     * 
-     * @param metaData
-     *            object describing the type of upgrade
-     */
-    protected abstract Resource doPerformUpgrade(UpgradeMetaData metaData) 
throws ConfigurationException;
-
-    /**
-     * Creates a metadata object describing the type of upgrade needed.
-     */
-    protected abstract UpgradeMetaData loadMetaData();
-
-    /**
-     * A default method for quick extraction of the project version from an XML
-     * file.
-     */
-    protected String loadProjectVersion() {
-
-        RootTagHandler rootHandler = new RootTagHandler();
-        URL url = projectSource.getURL();
-
-        InputStream in = null;
-
-        try {
-            in = url.openStream();
-            XMLReader parser = Util.createXmlReader();
-
-            parser.setContentHandler(rootHandler);
-            parser.setErrorHandler(rootHandler);
-            parser.parse(new InputSource(in));
-        } catch (SAXException e) {
-            // expected ... handler will terminate as soon as it finds a root
-            // tag.
-        } catch (Exception e) {
-            throw new ConfigurationException("Error reading configuration from 
%s", e, url);
-        } finally {
-            try {
-                if (in != null) {
-                    in.close();
-                }
-            } catch (IOException ioex) {
-                // ignoring...
-            }
-        }
-
-        return rootHandler.projectVersion != null ? rootHandler.projectVersion 
: UNKNOWN_VERSION;
-    }
-
-    /**
-     * Compares two String versions.
-     */
-    protected int compareVersions(String v1, String v2) {
-
-        if (v1.equals(v2)) {
-            return 0;
-        }
-
-        double v1Double = decodeVersion(v1);
-        double v2Double = decodeVersion(v2);
-        return v1Double < v2Double ? -1 : 1;
-    }
-
-    protected double decodeVersion(String version) {
-        if (version == null || version.trim().length() == 0) {
-            return 0;
-        }
-
-        // leave the first dot, and treat remaining as a fraction
-        // remove all non digit chars
-        StringBuilder buffer = new StringBuilder(version.length());
-        boolean dotProcessed = false;
-        for (int i = 0; i < version.length(); i++) {
-            char nextChar = version.charAt(i);
-            if (nextChar == '.' && !dotProcessed) {
-                dotProcessed = true;
-                buffer.append('.');
-            } else if (Character.isDigit(nextChar)) {
-                buffer.append(nextChar);
-            }
-        }
-
-        return Double.parseDouble(buffer.toString());
-    }
-
-    class RootTagHandler extends DefaultHandler {
-
-        private String projectVersion;
-
-        @Override
-        public void startElement(String uri, String localName, String qName, 
Attributes attributes) throws SAXException {
-
-            this.projectVersion = attributes.getValue("", "project-version");
-
-            // bail right away - we are not interested in reading this to the
-            // end
-            throw new SAXException("finished");
-        }
-    }
+       static final String UNKNOWN_VERSION = "0";
+
+       protected Resource projectSource;
+       protected UpgradeMetaData metaData;
+
+       public BaseUpgradeHandler(Resource projectSource) {
+
+               if (projectSource == null) {
+                       throw new NullPointerException("Null project source");
+               }
+
+               this.projectSource = projectSource;
+       }
+
+       /**
+        * Creates a single common EntityResolver for all project DataMaps, 
setting
+        * it as a namespace for all of them. This is needed for resolving 
cross-map
+        * relationships.
+        */
+       protected void attachToNamespace(DataChannelDescriptor 
channelDescriptor) {
+               EntityResolver entityResolver = new 
EntityResolver(channelDescriptor.getDataMaps());
+
+               for (DataMap map : entityResolver.getDataMaps()) {
+                       map.setNamespace(entityResolver);
+               }
+       }
+
+       @Override
+       public Resource getProjectSource() {
+               return projectSource;
+       }
+
+       @Override
+       public UpgradeMetaData getUpgradeMetaData() {
+               // no attempts at thread-safety... shouldn't be needed for 
upgrades
+               if (metaData == null) {
+                       metaData = loadMetaData();
+               }
+
+               return metaData;
+       }
+
+       @Override
+       public Resource performUpgrade() throws ConfigurationException {
+               UpgradeMetaData metaData = getUpgradeMetaData();
+               switch (metaData.getUpgradeType()) {
+               case DOWNGRADE_NEEDED:
+                       throw new ConfigurationException("Downgrade can not be 
performed");
+               case INTERMEDIATE_UPGRADE_NEEDED:
+                       throw new ConfigurationException("Upgrade can not be 
performed - intermediate version upgrade needed");
+               case UPGRADE_NEEDED:
+                       return doPerformUpgrade(metaData);
+               default:
+                       return getProjectSource();
+               }
+       }
+
+       /**
+        * Does the actual project upgrade, assuming the caller already verified
+        * that the upgrade is possible.
+        * 
+        * @param metaData
+        *            object describing the type of upgrade
+        */
+       protected abstract Resource doPerformUpgrade(UpgradeMetaData metaData) 
throws ConfigurationException;
+
+       /**
+        * Creates a metadata object describing the type of upgrade needed.
+        */
+       protected abstract UpgradeMetaData loadMetaData();
+
+       /**
+        * A default method for quick extraction of the project version from an 
XML
+        * file.
+        */
+       protected String loadProjectVersion() {
+
+               RootTagHandler rootHandler = new RootTagHandler();
+               URL url = projectSource.getURL();
+
+               try (InputStream in = url.openStream();) {
+
+                       XMLReader parser = Util.createXmlReader();
+
+                       parser.setContentHandler(rootHandler);
+                       parser.setErrorHandler(rootHandler);
+                       parser.parse(new InputSource(in));
+               } catch (SAXException e) {
+                       // expected ... handler will terminate as soon as it 
finds a root
+                       // tag.
+               } catch (Exception e) {
+                       throw new ConfigurationException("Error reading 
configuration from %s", e, url);
+               }
+
+               return rootHandler.projectVersion != null ? 
rootHandler.projectVersion : UNKNOWN_VERSION;
+       }
+
+       /**
+        * Compares two String versions.
+        */
+       protected int compareVersions(String v1, String v2) {
+
+               if (v1.equals(v2)) {
+                       return 0;
+               }
+
+               double v1Double = decodeVersion(v1);
+               double v2Double = decodeVersion(v2);
+               return v1Double < v2Double ? -1 : 1;
+       }
+
+       protected double decodeVersion(String version) {
+               if (version == null || version.trim().length() == 0) {
+                       return 0;
+               }
+
+               // leave the first dot, and treat remaining as a fraction
+               // remove all non digit chars
+               StringBuilder buffer = new StringBuilder(version.length());
+               boolean dotProcessed = false;
+               for (int i = 0; i < version.length(); i++) {
+                       char nextChar = version.charAt(i);
+                       if (nextChar == '.' && !dotProcessed) {
+                               dotProcessed = true;
+                               buffer.append('.');
+                       } else if (Character.isDigit(nextChar)) {
+                               buffer.append(nextChar);
+                       }
+               }
+
+               return Double.parseDouble(buffer.toString());
+       }
+
+       class RootTagHandler extends DefaultHandler {
+
+               private String projectVersion;
+
+               @Override
+               public void startElement(String uri, String localName, String 
qName, Attributes attributes) throws SAXException {
+
+                       this.projectVersion = attributes.getValue("", 
"project-version");
+
+                       // bail right away - we are not interested in reading 
this to the
+                       // end
+                       throw new SAXException("finished");
+               }
+       }
 }

Reply via email to