Author: [log in to unmask] Date: Thu Jan 1 23:08:18 2015 New Revision: 1820 Log: Add open and close of connection in converters if there is not a usable connection already. Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsObjectConverter.java java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsSeriesConverter.java Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsObjectConverter.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsObjectConverter.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsObjectConverter.java Thu Jan 1 23:08:18 2015 @@ -6,6 +6,7 @@ import org.hps.conditions.api.AbstractConditionsObjectCollection; import org.hps.conditions.api.ConditionsObject; +import org.hps.conditions.api.ConditionsObjectCollection; import org.hps.conditions.api.ConditionsObjectException; import org.hps.conditions.api.ConditionsRecord; import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection; @@ -65,93 +66,88 @@ // Get the DatabaseConditionsManager which is required for using this converter. DatabaseConditionsManager databaseConditionsManager = (DatabaseConditionsManager) conditionsManager; + // Setup connection if necessary. + boolean reopenedConnection = false; + if (!databaseConditionsManager.isConnected()) { + // Open a connection to the database. + databaseConditionsManager.openConnection(); + reopenedConnection = true; + } + // Get the TableMetaData for the type. TableMetaData tableMetaData = databaseConditionsManager.findTableMetaData(getType()); // Get the ConditionsRecordCollection with the run number assignments. ConditionsRecordCollection conditionsRecords = databaseConditionsManager.findConditionsRecords(name); - - // The records to use will be added to this collection, which may depend on multiple record disambiguation. - ConditionsRecordCollection filteredConditionsRecords = new ConditionsRecordCollection(); - - // Now we need to determine which ConditionsRecord objects to use according to configuration. + + // The record with the collection information. + ConditionsRecord conditionsRecord = null; + + // Now we need to determine which ConditionsRecord object to use. if (conditionsRecords.size() == 0) { // No conditions records were found for the key. + // FIXME: This should possibly just return an empty collection instead. throw new RuntimeException("No conditions were found with key: " + name); + } else if (conditionsRecords.size() == 1) { + // Use the single conditions set that was found. + conditionsRecord = conditionsRecords.get(0); } else if (conditionsRecords.size() > 1) { if (multipleCollections.equals(MultipleCollectionsAction.LAST_UPDATED)) { // Use the conditions set with the latest updated date. - filteredConditionsRecords.add(conditionsRecords.sortedByUpdated().get(conditionsRecords.size() - 1)); + conditionsRecord = conditionsRecords.sortedByUpdated().get(conditionsRecords.size() - 1); } else if (multipleCollections.equals(MultipleCollectionsAction.LAST_CREATED)){ // Use the conditions set with the latest created date. - filteredConditionsRecords.add(conditionsRecords.sortedByCreated().get(conditionsRecords.size() - 1)); + conditionsRecord = conditionsRecords.sortedByCreated().get(conditionsRecords.size() - 1); } else if (multipleCollections.equals(MultipleCollectionsAction.LATEST_RUN_START)) { // Use the conditions set with the greatest run start value. - filteredConditionsRecords.add(conditionsRecords.sortedByRunStart().get(conditionsRecords.size() - 1)); - } else if (multipleCollections.equals(MultipleCollectionsAction.COMBINE)) { - // Combine all the records. - filteredConditionsRecords.addAll(conditionsRecords); + conditionsRecord = conditionsRecords.sortedByRunStart().get(conditionsRecords.size() - 1); } else if (multipleCollections.equals(MultipleCollectionsAction.ERROR)) { - // The converter has been configured to throw an error when this happens! + // The converter has been configured to throw an error. throw new RuntimeException("Multiple ConditionsRecord object found for conditions key " + name); } - } else { - // Single record was found. - filteredConditionsRecords.addAll(conditionsRecords); - } + } - // Create a collection of objects to to return. - AbstractConditionsObjectCollection collection = null; - try { - // If there is a single ConditionsRecord, then it can be assigned to the collection. - ConditionsRecord collectionConditionsRecord = null; - if (filteredConditionsRecords.size() == 1) { - collectionConditionsRecord = filteredConditionsRecords.get(0); + // Create a collection of objects to return. + ConditionsObjectCollection collection = null; + try { + collection = createCollection(conditionsRecord, tableMetaData); + } catch (ConditionsObjectException e) { + throw new RuntimeException(e); + } + + // Get the table name. + String tableName = conditionsRecord.getTableName(); + + // Get the collection ID. + int collectionId = conditionsRecord.getCollectionId(); + + // Build a select query. + String query = QueryBuilder.buildSelect(tableName, collectionId, tableMetaData.getFieldNames(), "id ASC"); + + // Query the database to get the collection's rows. + ResultSet resultSet = databaseConditionsManager.selectQuery(query); + + try { + // Loop over the rows. + while (resultSet.next()) { + // Create a new ConditionsObject from this row. + ConditionsObject newObject = createConditionsObject(resultSet, tableMetaData); + + // Add the object to the collection. + collection.add(newObject); } - - // Create the collection with a ConditionsRecord that might be null. - collection = createCollection(collectionConditionsRecord, tableMetaData); - } catch (ConditionsObjectException e) { - throw new RuntimeException(e); - } - - // Open a database connection. - databaseConditionsManager.openConnection(); - - // Loop over all records, which could just be a single one. - for (ConditionsRecord conditionsRecord : filteredConditionsRecords) { - - // Get the table name. - String tableName = conditionsRecord.getTableName(); - - // Get the collection ID. - int collectionId = conditionsRecord.getCollectionId(); - - // Build a select query. - String query = QueryBuilder.buildSelect(tableName, collectionId, tableMetaData.getFieldNames(), "id ASC"); - - // Query the database to get the conditions collection's rows. - ResultSet resultSet = databaseConditionsManager.selectQuery(query); - - try { - // Loop over the rows. - while (resultSet.next()) { - // Create a new ConditionsObject from this row. - ConditionsObject newObject = createConditionsObject(resultSet, tableMetaData); - - // Add the object to the collection. - collection.add(newObject); - } - } catch (SQLException e) { - throw new RuntimeException(e); - } - - // Close the Statement and the ResultSet. - DatabaseUtilities.cleanup(resultSet); - } - - // Close the database connection. - databaseConditionsManager.closeConnection(); + } catch (SQLException e) { + // Some kind of database error occurred. + throw new RuntimeException(e); + } + + // Close the Statement and the ResultSet. + DatabaseUtilities.cleanup(resultSet); + + if (reopenedConnection) { + // Close connection if one was opened. + databaseConditionsManager.closeConnection(); + } return (T) collection; } Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java Thu Jan 1 23:08:18 2015 @@ -25,9 +25,13 @@ public ConditionsRecordCollection getData(ConditionsManager manager, String name) { DatabaseConditionsManager databaseConditionsManager = DatabaseConditionsManager.getInstance(); - - // Open the db connection. - databaseConditionsManager.openConnection(); + + // Setup connection if necessary. + boolean reopenedConnection = false; + if (!databaseConditionsManager.isConnected()) { + databaseConditionsManager.openConnection(); + reopenedConnection = true; + } TableMetaData tableMetaData = databaseConditionsManager.findTableMetaData(name); @@ -58,9 +62,10 @@ // Close the ResultSet and Statement. DatabaseUtilities.cleanup(resultSet); - // Close the db connection. - databaseConditionsManager.closeConnection(); - + if (reopenedConnection) { + databaseConditionsManager.closeConnection(); + } + return getType().cast(collection); } Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsSeriesConverter.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsSeriesConverter.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsSeriesConverter.java Thu Jan 1 23:08:18 2015 @@ -3,80 +3,82 @@ import java.sql.ResultSet; import java.sql.SQLException; -import org.hps.conditions.api.AbstractConditionsObjectCollection; import org.hps.conditions.api.ConditionsObject; +import org.hps.conditions.api.ConditionsObjectCollection; import org.hps.conditions.api.ConditionsObjectException; import org.hps.conditions.api.ConditionsRecord; import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection; import org.hps.conditions.api.ConditionsSeries; /** - * <p> - * This converter creates a <tt>ConditionsSeries</tt> which is a set of - * <tt>ConditionsObjectCollection</tt> objects with the same type. This can be - * used to retrieve sets of conditions that may overlap in time validity, such - * as sets of bad channels . - * </p> - * <p> - * Since type inference from the target variable is used in the - * {@link #createSeries(String)} method signature, there only needs to be one of - * these converters per {@link DatabaseConditionsManager}. The creation of the - * specific types is also done automatically, so each type of conditions object - * does not need its own converter class. - * </p> + * This converter creates a {@link org.hps.conditions.api.ConditionsSeries} which is a list of + * {@link org.hps.conditions.api.ConditionsObjectCollection} objects having the same type. + * This can be used to retrieve sets of conditions that may overlap in time validity. The user + * may then use whichever collections are of interest to them. + * + * @see org.hps.conditions.api.ConditionsSeries + * @see org.hps.conditions.api.ConditionsObjectCollection + * @see org.hps.conditions.api.ConditionsObject + * @see DatabaseConditionsManager + * + * @param <ObjectType> The type of the ConditionsObject. + * @param <CollectionType> The type of the collection. * * @author Jeremy McCormick <[log in to unmask]> */ -class ConditionsSeriesConverter { +// FIXME: The ObjectType and CollectionType should probably not extend in order to simplify the types. +class ConditionsSeriesConverter<ObjectType extends ConditionsObject, CollectionType extends ConditionsObjectCollection<ObjectType>> { - DatabaseConditionsManager conditionsManager = null; - - ConditionsSeriesConverter(DatabaseConditionsManager conditionsManager) { - if (conditionsManager == null) - throw new RuntimeException("The conditionsManager is null."); - this.conditionsManager = conditionsManager; + Class<ObjectType> objectType; + Class<CollectionType> collectionType; + + ConditionsSeriesConverter(Class<ObjectType> objectType, Class<CollectionType> collectionType) { + this.collectionType = collectionType; + this.objectType = objectType; } /** - * Create a <tt>ConditionsSeries</tt> which is a series of - * <tt>ConditionsObjectCollections</tt> of the same type, each of which have - * their own <tt>ConditionsRecord</tt>. This should be used for overlapping - * conditions, such as sets of bad channels that are combined together as in - * the test run. - * - * @param conditionsKey The name of the conditions key to retrieve from the conditions table. - * @return The <tt>ConditionsSeries</tt> matching <tt>conditionsKey</tt> - * which type inferred from target variable. - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - // FIXME: This should take a type name to enforce that all collections returned are of the same class. - public ConditionsSeries createSeries(String conditionsKey) { + * Create a new conditions series. + * @param tableName The name of the data table. + * @return The conditions series. + */ + @SuppressWarnings({ "unchecked" }) + ConditionsSeries<ObjectType, CollectionType> createSeries(String tableName) { + + if (tableName == null) { + throw new IllegalArgumentException("The tableName argument is null."); + } - conditionsManager.openConnection(); + DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance(); + + // Setup connection if necessary. + boolean reopenedConnection = false; + if (!conditionsManager.isConnected()) { + conditionsManager.openConnection(); + reopenedConnection = true; + } + + // Get the table meta data for the collection type. + TableMetaData tableMetaData = conditionsManager.findTableMetaData(collectionType); + if (tableMetaData == null) { + throw new RuntimeException("Table meta data for " + collectionType + " was not found."); + } - // Get the table meta data from the key given by the caller. - TableMetaData tableMetaData = conditionsManager.findTableMetaData(conditionsKey); - if (tableMetaData == null) - throw new RuntimeException("Table meta data for " + conditionsKey + " was not found."); + // Create a new conditions series. + ConditionsSeries<ObjectType, CollectionType> series = new ConditionsSeries<ObjectType, CollectionType>(objectType, collectionType); + + // Get the ConditionsRecord with the meta-data, which will use the current run number from the manager. + ConditionsRecordCollection conditionsRecords = conditionsManager.findConditionsRecords(tableName); - ConditionsSeries series = new ConditionsSeries(); - - // Get the ConditionsRecord with the meta-data, which will use the - // current run number from the manager. - ConditionsRecordCollection conditionsRecords = conditionsManager.findConditionsRecords(conditionsKey); - - // Loop over conditions records. This will usually just be one record. for (ConditionsRecord conditionsRecord : conditionsRecords) { - AbstractConditionsObjectCollection collection; + ConditionsObjectCollection<ObjectType> collection; try { - collection = ConditionsRecordConverter.createCollection(conditionsRecord, tableMetaData); + collection = (ConditionsObjectCollection<ObjectType>) + ConditionsRecordConverter.createCollection(conditionsRecord, tableMetaData); } catch (ConditionsObjectException e) { throw new RuntimeException(e); } - - // Get the table name. - String tableName = conditionsRecord.getTableName(); // Get the collection ID. int collectionId = conditionsRecord.getCollectionId(); @@ -93,9 +95,8 @@ // Create new ConditionsObject. ConditionsObject newObject = ConditionsRecordConverter.createConditionsObject(resultSet, tableMetaData); - // Add new object to collection, which will also assign it a - // collection ID if applicable. - collection.add(newObject); + // Add new object to collection. + collection.add((ObjectType) newObject); } } catch (SQLException e) { throw new RuntimeException(e); @@ -103,11 +104,13 @@ DatabaseUtilities.cleanup(resultSet); - series.add(collection); + series.add((CollectionType) collection); } - conditionsManager.closeConnection(); - + if (reopenedConnection) { + conditionsManager.closeConnection(); + } + // Return new collection. return series; }