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"); + } + } }
