Author: [log in to unmask]
Date: Wed Apr 15 14:29:14 2015
New Revision: 2716
Log:
Fix insert so it should work on all object types.
Modified:
java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
java/trunk/conditions/src/main/java/org/hps/conditions/database/QueryBuilder.java
Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
=============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java (original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java Wed Apr 15 14:29:14 2015
@@ -60,145 +60,40 @@
public final class DatabaseConditionsManager extends ConditionsManagerImplementation {
/**
+ * Name of system property that can be used to specify custom database connection parameters.
+ */
+ private static final String CONNECTION_PROPERTY = "org.hps.conditions.connection.file";
+
+ /**
+ * The default XML config.
+ */
+ private static final String DEFAULT_CONFIG = "/org/hps/conditions/config/conditions_database_prod.xml";
+
+ /**
+ * The connection properties resource for connecting to the default JLAB database.
+ */
+ private static final String DEFAULT_CONNECTION_PROPERTIES_RESOURCE = "/org/hps/conditions/config/jlab_connection.prop";
+
+ /**
+ * The Eng Run XML config.
+ */
+ private static final String ENGRUN_CONFIG = "/org/hps/conditions/config/conditions_database_engrun.xml";
+
+ /**
* Initialize the logger.
*/
private static Logger logger = LogUtil.create(DatabaseConditionsManager.class.getName(), new DefaultLogFormatter(),
Level.FINE);
/**
- * Create the global registry of conditions object converters.
- */
- private ConverterRegistry converters = ConverterRegistry.create();
-
- /**
- * Create the global registry of table meta data.
- */
- private TableRegistry tableRegistry = TableRegistry.create();
-
- /**
- * Name of system property that can be used to specify custom database connection parameters.
- */
- private static final String CONNECTION_PROPERTY = "org.hps.conditions.connection.file";
-
- /**
- * The connection properties file, if one is being used from the command line.
- */
- private File connectionPropertiesFile;
-
- /**
- * The current connection parameters.
- */
- private ConnectionParameters connectionParameters;
-
- /**
- * The current database connection.
- */
- private Connection connection;
-
- /**
- * True if manager is connected to the database.
- */
- private boolean isConnected = false;
-
- /**
- * Flag used to print connection parameters one time.
- */
- private boolean loggedConnectionParameters = false;
-
- /**
- * The default XML config.
- */
- private static final String DEFAULT_CONFIG = "/org/hps/conditions/config/conditions_database_prod.xml";
-
- /**
* The Test Run XML config.
*/
private static final String TEST_RUN_CONFIG = "/org/hps/conditions/config/conditions_database_testrun_2012.xml";
/**
- * The Eng Run XML config.
- */
- private static final String ENGRUN_CONFIG = "/org/hps/conditions/config/conditions_database_engrun.xml";
-
- /**
- * The connection properties resource for connecting to the default JLAB database.
- */
- private static final String DEFAULT_CONNECTION_PROPERTIES_RESOURCE = "/org/hps/conditions/config/jlab_connection.prop";
-
- /**
* The max value for a run to be considered Test Run.
*/
private static final int TEST_RUN_MAX_RUN = 1365;
-
- /**
- * The default ECAL detector name in the detector geometry.
- */
- private String ecalName = "Ecal";
-
- /**
- * The default SVT name in the detector geometry.
- */
- private String svtName = "Tracker";
-
- /**
- * The converter for creating the combined SVT conditions object.
- */
- private ConditionsConverter svtConverter;
-
- /**
- * The converter for creating the combined ECAL conditions object.
- */
- private ConditionsConverter ecalConverter;
-
- /**
- * The helper for setting up the SVT detector with its conditions information.
- */
- private SvtDetectorSetup svtSetup = new SvtDetectorSetup(svtName);
-
- /**
- * The currently active conditions tag.
- */
- private String tag = null;
-
- /**
- * True if the manager has been initialized, e.g. the {@link #setDetector(String, int)} method was called.
- */
- private boolean isInitialized = false;
-
- /**
- * True if the conditions system has been frozen and will ignore updates after it is initialized.
- */
- private boolean isFrozen = false;
-
- /**
- * True if the conditions manager was configured from an XML configuration resource or file.
- */
- private boolean isConfigured = false;
-
- /**
- * True to setup the SVT detector model with conditions.
- */
- private boolean setupSvtDetector = true;
-
- /**
- * True to freeze the system after initialization.
- */
- private boolean freezeAfterInitialize = false;
-
- /**
- * True to close the connection after initialization.
- */
- private boolean closeConnectionAfterInitialize = true;
-
- /**
- * True to cache all known conditions sets (from keys) during initialization.
- */
- private boolean cacheAllConditions = false;
-
- /**
- * True if current run number is from Test Run.
- */
- private boolean isTestRun = false;
static {
// Set default login timeout of 5 seconds.
@@ -206,21 +101,6 @@
}
/**
- * Class constructor. Calling this will automatically register this manager as the global default.
- */
- private DatabaseConditionsManager() {
- registerConditionsConverter(new DetectorConditionsConverter());
- setupConnectionFromSystemProperty();
- ConditionsManager.setDefaultConditionsManager(this);
- setRun(-1);
- for (AbstractConditionsObjectConverter converter : converters.values()) {
- // logger.fine("registering converter for " + converter.getType());
- registerConditionsConverter(converter);
- }
- addConditionsListener(svtSetup);
- }
-
- /**
* Get the static instance of this class.
*
* @return the static instance of the manager
@@ -230,8 +110,7 @@
logger.finest("getting conditions manager instance");
// Is there no manager installed yet?
- if (!ConditionsManager.isSetup() ||
- !(ConditionsManager.defaultInstance() instanceof DatabaseConditionsManager)) {
+ if (!ConditionsManager.isSetup() || !(ConditionsManager.defaultInstance() instanceof DatabaseConditionsManager)) {
logger.finest("creating new DatabaseConditionsManager");
// Create a new instance if necessary, which will install it globally as the default.
new DatabaseConditionsManager();
@@ -251,6 +130,25 @@
}
/**
+ * Get the Logger for this class, which can be used by related sub-classes if they do not have their own logger.
+ *
+ * @return the Logger for this class
+ */
+ public static Logger getLogger() {
+ return logger;
+ }
+
+ /**
+ * Utility method to determine if a run number is from the 2012 Test Run.
+ *
+ * @param runNumber the run number
+ * @return <code>true</code> if run number is from the Test Run
+ */
+ public static boolean isTestRun(final int runNumber) {
+ return runNumber > 0 && runNumber <= TEST_RUN_MAX_RUN;
+ }
+
+ /**
* Reset the global static instance of the conditions manager to a new object.
*/
public static synchronized void resetInstance() {
@@ -259,50 +157,138 @@
}
/**
- * Set the log level.
- *
- * @param level the new log level
- */
- public void setLogLevel(final Level level) {
- logger.config("setting log level to " + level);
- logger.setLevel(level);
- logger.getHandlers()[0].setLevel(level);
- svtSetup.setLogLevel(level);
- }
-
- /**
- * Open the database connection.
- *
- * @return <code>true</code> if a connection was opened; <code>false</code> if using an existing connection.
- */
- public synchronized boolean openConnection() {
- boolean openedConnection = false;
- if (!isConnected) {
- // Do the connection parameters need to be figured out automatically?
- if (connectionParameters == null) {
- // Setup the default read-only connection, which will choose a SLAC or JLab database.
- connectionParameters = ConnectionParameters.fromResource(DEFAULT_CONNECTION_PROPERTIES_RESOURCE);
- }
-
- if (!loggedConnectionParameters) {
- // Print out detailed info to the log on first connection within the job.
- logger.info("opening connection ... " + '\n' + "connection: "
- + connectionParameters.getConnectionString() + '\n' + "host: "
- + connectionParameters.getHostname() + '\n' + "port: " + connectionParameters.getPort() + '\n'
- + "user: " + connectionParameters.getUser() + '\n' + "database: "
- + connectionParameters.getDatabase());
- loggedConnectionParameters = true;
- }
-
- // Create the connection using the parameters.
- connection = connectionParameters.createConnection();
- isConnected = true;
- openedConnection = true;
- }
- logger.info("connection opened successfully");
-
- // Flag to indicate whether an existing connection was used or not.
- return openedConnection;
+ * True to cache all known conditions sets (from keys) during initialization.
+ */
+ private boolean cacheAllConditions = false;
+
+ /**
+ * True to close the connection after initialization.
+ */
+ private boolean closeConnectionAfterInitialize = true;
+
+ /**
+ * The current database connection.
+ */
+ private Connection connection;
+
+ /**
+ * The current connection parameters.
+ */
+ private ConnectionParameters connectionParameters;
+
+ /**
+ * The connection properties file, if one is being used from the command line.
+ */
+ private File connectionPropertiesFile;
+
+ /**
+ * Create the global registry of conditions object converters.
+ */
+ private final ConverterRegistry converters = ConverterRegistry.create();
+
+ /**
+ * The converter for creating the combined ECAL conditions object.
+ */
+ private ConditionsConverter ecalConverter;
+
+ /**
+ * The default ECAL detector name in the detector geometry.
+ */
+ private String ecalName = "Ecal";
+
+ /**
+ * True to freeze the system after initialization.
+ */
+ private boolean freezeAfterInitialize = false;
+
+ /**
+ * True if the conditions manager was configured from an XML configuration resource or file.
+ */
+ private boolean isConfigured = false;
+
+ /**
+ * True if manager is connected to the database.
+ */
+ private boolean isConnected = false;
+
+ /**
+ * True if the conditions system has been frozen and will ignore updates after it is initialized.
+ */
+ private boolean isFrozen = false;
+
+ /**
+ * True if the manager has been initialized, e.g. the {@link #setDetector(String, int)} method was called.
+ */
+ private boolean isInitialized = false;
+
+ /**
+ * True if current run number is from Test Run.
+ */
+ private boolean isTestRun = false;
+
+ /**
+ * Flag used to print connection parameters one time.
+ */
+ private boolean loggedConnectionParameters = false;
+
+ /**
+ * True to setup the SVT detector model with conditions.
+ */
+ private boolean setupSvtDetector = true;
+
+ /**
+ * The converter for creating the combined SVT conditions object.
+ */
+ private ConditionsConverter svtConverter;
+
+ /**
+ * The default SVT name in the detector geometry.
+ */
+ private String svtName = "Tracker";
+
+ /**
+ * The helper for setting up the SVT detector with its conditions information.
+ */
+ private final SvtDetectorSetup svtSetup = new SvtDetectorSetup(this.svtName);
+
+ /**
+ * Create the global registry of table meta data.
+ */
+ private final TableRegistry tableRegistry = TableRegistry.create();
+
+ /**
+ * The currently active conditions tag.
+ */
+ private String tag = null;
+
+ /**
+ * Class constructor. Calling this will automatically register this manager as the global default.
+ */
+ private DatabaseConditionsManager() {
+ registerConditionsConverter(new DetectorConditionsConverter());
+ setupConnectionFromSystemProperty();
+ ConditionsManager.setDefaultConditionsManager(this);
+ setRun(-1);
+ for (final AbstractConditionsObjectConverter converter : this.converters.values()) {
+ // logger.fine("registering converter for " + converter.getType());
+ registerConditionsConverter(converter);
+ }
+ addConditionsListener(this.svtSetup);
+ }
+
+ /**
+ * Cache conditions sets for all known tables.
+ */
+ private void cacheConditionsSets() {
+ for (final TableMetaData meta : this.tableRegistry.values()) {
+ try {
+ logger.fine("caching conditions " + meta.getKey() + " with type "
+ + meta.getCollectionClass().getCanonicalName());
+ getCachedConditions(meta.getCollectionClass(), meta.getKey());
+ } catch (final Exception e) {
+ logger.warning("could not cache conditions " + meta.getKey());
+ }
+ }
}
/**
@@ -310,23 +296,23 @@
*/
public synchronized void closeConnection() {
logger.fine("closing connection");
- if (connection != null) {
+ if (this.connection != null) {
try {
- if (!connection.isClosed()) {
- connection.close();
+ if (!this.connection.isClosed()) {
+ this.connection.close();
}
- } catch (SQLException e) {
+ } catch (final SQLException e) {
throw new RuntimeException(e);
}
}
- connection = null;
- isConnected = false;
+ this.connection = null;
+ this.isConnected = false;
logger.info("connection closed");
}
/**
* Close the database connection but only if there was a connection opened based on the flag. Otherwise, it should
- * be left open. Used in conjunction with return value of {@link #openConnection()}.
+ * be left open. Used in conjunction with return value of {@link #openConnection()}.
*
* @param connectionOpened <code>true</code> to close the connection; <code>false</code> to leave it open
*/
@@ -334,170 +320,6 @@
if (connectionOpened) {
closeConnection();
}
- }
-
- /**
- * Get a conditions series with one or more collections.
- *
- * @param collectionType the type of the collection
- * @param tableName the name of the data table
- * @param <ObjectType> the type of the conditions object
- * @param <CollectionType> the type of the conditions collection
- * @return the conditions series
- */
- @SuppressWarnings("unchecked")
- public
- <ObjectType extends ConditionsObject, CollectionType extends ConditionsObjectCollection<ObjectType>>
- ConditionsSeries<ObjectType, CollectionType> getConditionsSeries(
- final Class<CollectionType> collectionType, final String tableName) {
-
- final TableMetaData metaData = tableRegistry.get(tableName);
- if (metaData == null) {
- throw new IllegalArgumentException("No table metadata found for type " + collectionType.getName());
- }
- if (!metaData.getCollectionClass().equals(collectionType)) {
- throw new IllegalArgumentException("The type " + collectionType.getName() + " does not match the class "
- + metaData.getCollectionClass().getName() + " from the meta data");
- }
- final Class<? extends ConditionsObject> objectType = metaData.getObjectClass();
- final ConditionsSeriesConverter<ObjectType, CollectionType> converter =
- new ConditionsSeriesConverter(objectType, collectionType);
- return converter.createSeries(tableName);
- }
-
- /**
- * This method handles changes to the detector name and run number. It is called every time an LCSim event is
- * created, and so it has internal logic to figure out if the conditions system actually needs to be updated.
- */
- @Override
- public synchronized void setDetector(final String detectorName, final int runNumber)
- throws ConditionsNotFoundException {
-
- logger.finest("setDetector " + detectorName + " with run number " + runNumber);
-
- if (detectorName == null) {
- throw new IllegalArgumentException("The detectorName argument is null.");
- }
-
- if (!isInitialized || !detectorName.equals(getDetector()) || runNumber != getRun()) {
- if (!isFrozen) {
- logger.info("new detector " + detectorName + " and run #" + runNumber);
- initialize(detectorName, runNumber);
- } else {
- logger.finest("Conditions changed but will be ignored because manager is frozen.");
- }
- }
- }
-
- /**
- * Utility method to determine if a run number is from the 2012 Test Run.
- *
- * @param runNumber the run number
- * @return <code>true</code> if run number is from the Test Run
- */
- public static boolean isTestRun(final int runNumber) {
- return runNumber > 0 && runNumber <= TEST_RUN_MAX_RUN;
- }
-
- /**
- * Return <code>true</code> if Test Run configuration is active
- *
- * @return <code>true</code> if Test Run configuration is active
- */
- public boolean isTestRun() {
- return isTestRun;
- }
-
- /**
- * Get the current LCSim compact <code>Detector</code> object with the geometry and detector model.
- *
- * @return the detector object
- */
- public Detector getDetectorObject() {
- return getCachedConditions(Detector.class, "compact.xml").getCachedData();
- }
-
- /**
- * Configure some properties of this object from an XML file
- *
- * @param file the XML file
- */
- public void setXmlConfig(final File file) {
- logger.config("setting XML config from file " + file.getPath());
- if (!file.exists()) {
- throw new IllegalArgumentException("The config file does not exist: " + file.getPath());
- }
- try {
- configure(new FileInputStream(file));
- } catch (FileNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Configure this object from an embedded XML resource.
- *
- * @param resource the embedded XML resource
- */
- public void setXmlConfig(final String resource) {
- logger.config("setting XML config from resource " + resource);
- final InputStream is = getClass().getResourceAsStream(resource);
- configure(is);
- }
-
- /**
- * Set the path to a properties file containing connection settings.
- *
- * @param file the properties file
- */
- public void setConnectionProperties(final File file) {
- logger.config("setting connection properties file " + file.getPath());
- if (!file.exists()) {
- throw new IllegalArgumentException("The connection properties file does not exist: "
- + connectionPropertiesFile.getPath());
- }
- connectionParameters = ConnectionParameters.fromProperties(file);
- }
-
- /**
- * Set the connection parameters of the conditions database.
- *
- * @param connectionParameters the connection parameters
- */
- public void setConnectionParameters(final ConnectionParameters connectionParameters) {
- this.connectionParameters = connectionParameters;
- }
-
- /**
- * Set the connection parameters from an embedded resource location.
- *
- * @param resource the classpath resource location
- */
- public void setConnectionResource(final String resource) {
- logger.config("setting connection resource " + resource);
- connectionParameters = ConnectionParameters.fromResource(resource);
- }
-
- /**
- * Get the next collection ID for a database conditions table.
- *
- * @param tableName the name of the table
- * @return the next collection ID
- */
- public synchronized int getNextCollectionID(final String tableName) {
- final boolean openedConnection = openConnection();
- final ResultSet resultSet = selectQuery("SELECT MAX(collection_id)+1 FROM " + tableName);
- int collectionId = 1;
- try {
- resultSet.next();
- collectionId = resultSet.getInt(1);
- } catch (SQLException e) {
- e.printStackTrace();
- logger.warning(e.getMessage());
- }
- logger.fine("new collection ID " + collectionId + " created for table " + tableName);
- closeConnection(openedConnection);
- return collectionId;
}
/**
@@ -512,64 +334,42 @@
final ResultSet resultSet = selectQuery(sql);
try {
resultSet.last();
- } catch (SQLException e) {
+ } catch (final SQLException e) {
e.printStackTrace();
}
int rowCount = 0;
try {
rowCount = resultSet.getRow();
- } catch (SQLException e) {
+ } catch (final SQLException e) {
e.printStackTrace();
}
return rowCount != 0;
}
/**
- * This method can be used to perform a database SELECT query.
- *
- * @param query the SQL query string
- * @return the <code>ResultSet</code> from the query
- * @throws RuntimeException if there is a query error
- */
- ResultSet selectQuery(final String query) {
- logger.fine("executing SQL select query ..." + '\n' + query);
- ResultSet result = null;
- Statement statement = null;
- try {
- statement = connection.createStatement();
- result = statement.executeQuery(query);
- } catch (SQLException x) {
- throw new RuntimeException("Error in query: " + query, x);
- }
- return result;
- }
-
- /**
- * Perform a SQL query with an update command like INSERT, DELETE or UPDATE.
- *
- * @param query the SQL query string
- * @return the keys of the rows affected
- */
- public List<Integer> updateQuery(final String query) {
- final boolean openedConnection = openConnection();
- logger.fine("executing SQL update query ..." + '\n' + query);
- final List<Integer> keys = new ArrayList<Integer>();
- Statement statement = null;
- ResultSet resultSet = null;
- try {
- statement = connection.createStatement();
- statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
- resultSet = statement.getGeneratedKeys();
- while (resultSet.next()) {
- final int key = resultSet.getInt(1);
- keys.add(key);
- }
- } catch (SQLException x) {
- throw new RuntimeException("Error in SQL query: " + query, x);
- }
- DatabaseUtilities.cleanup(resultSet);
- closeConnection(openedConnection);
- return keys;
+ * Configure this class from an <code>InputStream</code> which should point to an XML document.
+ *
+ * @param in the InputStream which should be in XML format
+ */
+ private void configure(final InputStream in) {
+ if (!this.isConfigured) {
+ final SAXBuilder builder = new SAXBuilder();
+ Document config = null;
+ try {
+ config = builder.build(in);
+ } catch (JDOMException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ loadConfiguration(config);
+ try {
+ in.close();
+ } catch (final IOException e) {
+ logger.warning(e.getMessage());
+ }
+ this.isConfigured = true;
+ } else {
+ logger.warning("System is already configured, so call to configure is ignored!");
+ }
}
/**
@@ -584,7 +384,7 @@
"conditions").getCachedData();
logger.fine("searching for conditions with name " + name + " in " + runConditionsRecords.size() + " records");
final ConditionsRecordCollection foundConditionsRecords = new ConditionsRecordCollection();
- for (ConditionsRecord record : runConditionsRecords) {
+ for (final ConditionsRecord record : runConditionsRecords) {
if (record.getName().equals(name)) {
if (matchesTag(record)) {
foundConditionsRecords.add(record);
@@ -595,18 +395,41 @@
}
}
}
- logger.fine("found " + foundConditionsRecords.size() + " conditions records matching tag " + tag);
+ logger.fine("found " + foundConditionsRecords.size() + " conditions records matching tag " + this.tag);
return foundConditionsRecords;
}
/**
- * True if there is a conditions record with the given name.
- *
- * @param name the conditions record name (usually will match to table name)
- * @return <code>true</code> if a conditions record exists with the given name
- */
- public boolean hasConditionsRecord(final String name) {
- return !findConditionsRecords(name).isEmpty();
+ * Find table information from the collection type.
+ *
+ * @param type the collection type
+ * @return the table information or <code>null</code> if does not exist
+ */
+ public List<TableMetaData> findTableMetaData(final Class<?> type) {
+ return this.tableRegistry.findByCollectionType(type);
+ }
+
+ /**
+ * Find table information from the name.
+ *
+ * @param name the name of the table
+ * @return the table information or <code>null</code> if does not exist
+ */
+ public TableMetaData findTableMetaData(final String name) {
+ return this.tableRegistry.findByTableName(name);
+ }
+
+ /**
+ * This method can be called to "freeze" the conditions system so that any subsequent updates to run number or
+ * detector name will be ignored.
+ */
+ public synchronized void freeze() {
+ if (getDetector() != null && getRun() != -1) {
+ this.isFrozen = true;
+ logger.config("conditions system is frozen");
+ } else {
+ logger.warning("conditions system cannot be frozen because it is not initialized yet");
+ }
}
/**
@@ -618,14 +441,13 @@
public ConditionsRecordCollection getConditionsRecords() {
logger.finer("getting conditions records ...");
final ConditionsRecordCollection conditionsRecords = new ConditionsRecordCollection();
- for (TableMetaData tableMetaData : tableRegistry.values()) {
+ for (final TableMetaData tableMetaData : this.tableRegistry.values()) {
try {
- final ConditionsRecordCollection foundConditionsRecords =
- findConditionsRecords(tableMetaData.getKey());
+ final ConditionsRecordCollection foundConditionsRecords = findConditionsRecords(tableMetaData.getKey());
logger.finer("found " + foundConditionsRecords.size() + " collections with name "
+ tableMetaData.getKey());
conditionsRecords.addAll(foundConditionsRecords);
- } catch (Exception e) {
+ } catch (final Exception e) {
e.printStackTrace();
logger.warning(e.getMessage());
}
@@ -636,6 +458,42 @@
}
/**
+ * Get a conditions series with one or more collections.
+ *
+ * @param collectionType the type of the collection
+ * @param tableName the name of the data table
+ * @param <ObjectType> the type of the conditions object
+ * @param <CollectionType> the type of the conditions collection
+ * @return the conditions series
+ */
+ @SuppressWarnings("unchecked")
+ public <ObjectType extends ConditionsObject, CollectionType extends ConditionsObjectCollection<ObjectType>> ConditionsSeries<ObjectType, CollectionType> getConditionsSeries(
+ final Class<CollectionType> collectionType, final String tableName) {
+
+ final TableMetaData metaData = this.tableRegistry.get(tableName);
+ if (metaData == null) {
+ throw new IllegalArgumentException("No table metadata found for type " + collectionType.getName());
+ }
+ if (!metaData.getCollectionClass().equals(collectionType)) {
+ throw new IllegalArgumentException("The type " + collectionType.getName() + " does not match the class "
+ + metaData.getCollectionClass().getName() + " from the meta data");
+ }
+ final Class<? extends ConditionsObject> objectType = metaData.getObjectClass();
+ final ConditionsSeriesConverter<ObjectType, CollectionType> converter = new ConditionsSeriesConverter(
+ objectType, collectionType);
+ return converter.createSeries(tableName);
+ }
+
+ /**
+ * Get the current LCSim compact <code>Detector</code> object with the geometry and detector model.
+ *
+ * @return the detector object
+ */
+ public Detector getDetectorObject() {
+ return getCachedConditions(Detector.class, "compact.xml").getCachedData();
+ }
+
+ /**
* Get the combined ECAL conditions for this run.
*
* @return the combined ECAL conditions
@@ -645,197 +503,52 @@
}
/**
+ * Get the name of the ECAL in the detector geometry.
+ *
+ * @return the name of the ECAL
+ */
+ public String getEcalName() {
+ return this.ecalName;
+ }
+
+ /**
+ * Get the subdetector object of the ECAL.
+ *
+ * @return the ECAL subdetector
+ */
+ public Subdetector getEcalSubdetector() {
+ return this.getDetectorObject().getSubdetector(this.ecalName);
+ }
+
+ /**
+ * Get the next collection ID for a database conditions table.
+ *
+ * @param tableName the name of the table
+ * @return the next collection ID
+ */
+ public synchronized int getNextCollectionID(final String tableName) {
+ final boolean openedConnection = openConnection();
+ final ResultSet resultSet = selectQuery("SELECT MAX(collection_id)+1 FROM " + tableName);
+ int collectionId = 1;
+ try {
+ resultSet.next();
+ collectionId = resultSet.getInt(1);
+ } catch (final SQLException e) {
+ e.printStackTrace();
+ logger.warning(e.getMessage());
+ }
+ logger.fine("new collection ID " + collectionId + " created for table " + tableName);
+ closeConnection(openedConnection);
+ return collectionId;
+ }
+
+ /**
* Get the combined SVT conditions for this run.
*
* @return the combined SVT conditions
*/
public SvtConditions getSvtConditions() {
return this.getCachedConditions(SvtConditions.class, "svt_conditions").getCachedData();
- }
-
- /**
- * This method can be called to "freeze" the conditions system so that any subsequent updates to run number or
- * detector name will be ignored.
- */
- public synchronized void freeze() {
- if (getDetector() != null && getRun() != -1) {
- isFrozen = true;
- logger.config("conditions system is frozen");
- } else {
- logger.warning("conditions system cannot be frozen because it is not initialized yet");
- }
- }
-
- /**
- * Un-freeze the conditions system so that updates will be received again.
- */
- public synchronized void unfreeze() {
- isFrozen = false;
- logger.info("conditions system unfrozen");
- }
-
- /**
- * True if conditions system is frozen
- *
- * @return <code>true</code> if conditions system is currently frozen
- */
- public boolean isFrozen() {
- return isFrozen;
- }
-
- /**
- * Set a tag used to filter the accessible conditions records
- *
- * @param tag the tag value used to filter returned conditions records
- */
- public void setTag(final String tag) {
- this.tag = tag;
- logger.info("using conditions tag: " + tag);
- }
-
- /**
- * Insert a collection of ConditionsObjects into the database.
- *
- * @param collection the collection to insert
- * @param <ObjectType> the type of the conditions object
- * @throws SQLException if there is a database or SQL error
- * @throws ConditionsObjectException if there is a problem inserting the object
- */
- public <ObjectType extends ConditionsObject> void insertCollection(
- final ConditionsObjectCollection<ObjectType> collection)
- throws SQLException, ConditionsObjectException {
-
- if (collection == null) {
- throw new IllegalArgumentException("The collection is null.");
- }
- if (collection.size() == 0) {
- throw new IllegalArgumentException("The collection is empty.");
- }
-
- final TableMetaData tableMetaData = collection.getTableMetaData();
- if (tableMetaData == null) {
- final List<TableMetaData> metaDataList = tableRegistry.findByCollectionType(collection.getClass());
- if (metaDataList == null) {
- // This is a fatal error because no meta data is available for the type.
- throw new ConditionsObjectException("Failed to find meta data for type: " + collection.getClass());
- }
- }
- if (collection.getCollectionId() == -1) {
- try {
- collection.setCollectionId(getNextCollectionID(tableMetaData.getTableName()));
- } catch (ConditionsObjectException e) {
- throw new RuntimeException(e);
- }
- }
- // FIXME: If collection ID is already set this should be an error!
-
- logger.info("inserting collection with ID " + collection.getCollectionId() + " and key "
- + tableMetaData.getKey() + " into table " + tableMetaData.getTableName());
-
- final boolean openedConnection = openConnection();
-
- PreparedStatement preparedStatement = null;
-
- try {
- connection.setAutoCommit(false);
- logger.fine("starting insert transaction");
- final String sql = QueryBuilder.buildPreparedInsert(
- tableMetaData.getTableName(), collection.iterator().next());
- preparedStatement = connection.prepareStatement(sql);
- logger.fine("using prepared statement: " + sql);
- final int collectionId = collection.getCollectionId();
- for (ConditionsObject object : collection) {
- preparedStatement.setObject(1, collectionId);
- int parameterIndex = 2;
- for (Entry<String, Object> entry : object.getFieldValues().entrySet()) {
- preparedStatement.setObject(parameterIndex, entry.getValue());
- ++parameterIndex;
- }
- preparedStatement.executeUpdate();
- }
- connection.commit();
- logger.fine("committed transaction");
- } catch (Exception e) {
- e.printStackTrace();
- logger.warning(e.getMessage());
- logger.warning("rolling back transaction");
- connection.rollback();
- logger.warning("transaction was rolled back");
- } finally {
- connection.setAutoCommit(true);
- }
-
- try {
- preparedStatement.close();
- } catch (Exception e) {
- }
-
- closeConnection(openedConnection);
- }
-
- /**
- * Check if connected to the database.
- *
- * @return <code>true</code> if connected
- */
- public boolean isConnected() {
- return isConnected;
- }
-
- /**
- * Get the Logger for this class, which can be used by related sub-classes if they do not have their own logger.
- *
- * @return the Logger for this class
- */
- public static Logger getLogger() {
- return logger;
- }
-
- /**
- * Find table information from the name.
- *
- * @param name the name of the table
- * @return the table information or <code>null</code> if does not exist
- */
- public TableMetaData findTableMetaData(final String name) {
- return tableRegistry.findByTableName(name);
- }
-
- /**
- * Find table information from the collection type.
- *
- * @param type the collection type
- * @return the table information or <code>null</code> if does not exist
- */
- public List<TableMetaData> findTableMetaData(final Class<?> type) {
- return tableRegistry.findByCollectionType(type);
- }
-
- /**
- * Get the name of the ECAL in the detector geometry.
- *
- * @return the name of the ECAL
- */
- public String getEcalName() {
- return ecalName;
- }
-
- /**
- * Get the subdetector object of the ECAL.
- *
- * @return the ECAL subdetector
- */
- public Subdetector getEcalSubdetector() {
- return this.getDetectorObject().getSubdetector(ecalName);
- }
-
- /**
- * True if conditions manager is properly initialized.
- *
- * @return <code>true</code> if the manager is initialized
- */
- public boolean isInitialized() {
- return isInitialized;
}
/**
@@ -852,17 +565,17 @@
while (rs.next()) {
tags.add(rs.getString(1));
}
- } catch (SQLException e) {
+ } catch (final SQLException e) {
throw new RuntimeException(e);
}
try {
rs.close();
- } catch (SQLException e) {
+ } catch (final SQLException e) {
logger.log(Level.WARNING, "error closing ResultSet", e);
}
final StringBuffer sb = new StringBuffer();
sb.append("found unique conditions tags: ");
- for (String tag : tags) {
+ for (final String tag : tags) {
sb.append(tag + " ");
}
sb.setLength(sb.length() - 1);
@@ -872,9 +585,19 @@
}
/**
- * Perform all necessary initialization, including setup of the XML configuration and loading of conditions
- * onto the Detector. This is called from the {@link #setDetector(String, int)} method to setup the manager
- * for a new run or detector.
+ * True if there is a conditions record with the given name.
+ *
+ * @param name the conditions record name (usually will match to table name)
+ * @return <code>true</code> if a conditions record exists with the given name
+ */
+ public boolean hasConditionsRecord(final String name) {
+ return !findConditionsRecords(name).isEmpty();
+ }
+
+ /**
+ * Perform all necessary initialization, including setup of the XML configuration and loading of conditions onto the
+ * Detector. This is called from the {@link #setDetector(String, int)} method to setup the manager for a new run or
+ * detector.
*
* @param detectorName the name of the detector model
* @param runNumber the run number
@@ -885,7 +608,7 @@
logger.config("initializing with detector " + detectorName + " and run " + runNumber);
// Is not configured yet?
- if (!isConfigured) {
+ if (!this.isConfigured) {
if (isTestRun(runNumber)) {
// This looks like the Test Run so use the custom configuration for it.
setXmlConfig(DatabaseConditionsManager.TEST_RUN_CONFIG);
@@ -903,8 +626,8 @@
registerConverters();
// Enable or disable the setup of the SVT detector.
- logger.fine("enabling SVT setup: " + setupSvtDetector);
- svtSetup.setEnabled(setupSvtDetector);
+ logger.fine("enabling SVT setup: " + this.setupSvtDetector);
+ this.svtSetup.setEnabled(this.setupSvtDetector);
// Open the database connection.
openConnection();
@@ -914,26 +637,26 @@
super.setDetector(detectorName, runNumber);
// Should all conditions sets be cached?
- if (cacheAllConditions) {
+ if (this.cacheAllConditions) {
// Cache the conditions sets of all registered converters.
logger.fine("caching all conditions sets ...");
cacheConditionsSets();
}
- if (closeConnectionAfterInitialize) {
+ if (this.closeConnectionAfterInitialize) {
logger.fine("closing connection after initialization");
// Close the connection.
closeConnection();
}
// Should the conditions system be frozen now?
- if (freezeAfterInitialize) {
+ if (this.freezeAfterInitialize) {
// Freeze the conditions system so subsequent updates will be ignored.
freeze();
logger.config("system was frozen after initialization");
}
- isInitialized = true;
+ this.isInitialized = true;
logger.info("conditions system initialized successfully");
@@ -942,59 +665,188 @@
}
/**
- * Register the conditions converters with the manager.
- */
- private void registerConverters() {
- if (svtConverter != null) {
- // Remove old SVT converter.
- removeConditionsConverter(svtConverter);
- }
-
- if (ecalConverter != null) {
- // Remove old ECAL converter.
- registerConditionsConverter(ecalConverter);
- }
-
- // Is configured for TestRun?
- if (isTestRun()) {
- // Load Test Run specific converters.
- svtConverter = new TestRunSvtConditionsConverter();
- ecalConverter = new TestRunEcalConditionsConverter();
- logger.config("registering Test Run conditions converters");
- } else {
- // Load the default converters.
- svtConverter = new SvtConditionsConverter();
- ecalConverter = new EcalConditionsConverter();
- logger.config("registering default conditions converters");
- }
- registerConditionsConverter(svtConverter);
- registerConditionsConverter(ecalConverter);
- }
-
- /**
- * Set the name of the ECAL sub-detector.
- *
- * @param ecalName the name of the ECAL subdetector
- */
- private void setEcalName(final String ecalName) {
- if (ecalName == null) {
- throw new IllegalArgumentException("The ecalName is null");
- }
- this.ecalName = ecalName;
- logger.info("ECAL name set to " + ecalName);
- }
-
- /**
- * Set the name of the SVT subdetector.
- *
- * @param svtName the name of the SVT subdetector
- */
- private void setSvtName(final String svtName) {
- if (svtName == null) {
- throw new IllegalArgumentException("The svtName is null");
- }
- this.svtName = svtName;
- logger.info("SVT name set to " + ecalName);
+ * Insert a collection of ConditionsObjects into the database.
+ *
+ * @param collection the collection to insert
+ * @param <ObjectType> the type of the conditions object
+ * @throws SQLException if there is a database or SQL error
+ * @throws ConditionsObjectException if there is a problem inserting the object
+ */
+ public <ObjectType extends ConditionsObject> void insertCollection(
+ final ConditionsObjectCollection<ObjectType> collection) throws SQLException, ConditionsObjectException {
+
+ if (collection == null) {
+ throw new IllegalArgumentException("The collection is null.");
+ }
+ if (collection.size() == 0) {
+ throw new IllegalArgumentException("The collection is empty.");
+ }
+
+ TableMetaData tableMetaData = collection.getTableMetaData();
+ if (tableMetaData == null) {
+ final List<TableMetaData> metaDataList = this.tableRegistry.findByCollectionType(collection.getClass());
+ if (metaDataList == null) {
+ // This is a fatal error because no meta data is available for the type.
+ throw new ConditionsObjectException("Failed to find meta data for type: " + collection.getClass());
+ }
+ tableMetaData = metaDataList.get(0);
+ }
+ if (collection.getCollectionId() == -1) {
+ try {
+ collection.setCollectionId(getNextCollectionID(tableMetaData.getTableName()));
+ } catch (final ConditionsObjectException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // FIXME: If collection ID is already set this should be an error!
+
+ logger.info("inserting collection with ID " + collection.getCollectionId() + " and key "
+ + tableMetaData.getKey() + " into table " + tableMetaData.getTableName());
+
+ final boolean openedConnection = openConnection();
+
+ PreparedStatement preparedStatement = null;
+
+ try {
+ this.connection.setAutoCommit(false);
+ logger.fine("starting insert transaction");
+ final String sql = QueryBuilder.buildPreparedInsert(tableMetaData.getTableName(), collection.iterator()
+ .next());
+ preparedStatement = this.connection.prepareStatement(sql);
+ logger.fine("using prepared statement: " + sql);
+ final int collectionId = collection.getCollectionId();
+ for (final ConditionsObject object : collection) {
+ preparedStatement.setObject(1, collectionId);
+ int parameterIndex = 2;
+ if (object instanceof ConditionsRecord) {
+ parameterIndex = 1;
+ }
+ for (final Entry<String, Object> entry : object.getFieldValues().entrySet()) {
+ preparedStatement.setObject(parameterIndex, entry.getValue());
+ ++parameterIndex;
+ }
+ preparedStatement.executeUpdate();
+ }
+ this.connection.commit();
+ logger.fine("committed transaction");
+ } catch (final Exception e) {
+ e.printStackTrace();
+ logger.warning(e.getMessage());
+ logger.warning("rolling back transaction");
+ this.connection.rollback();
+ logger.warning("transaction was rolled back");
+ } finally {
+ this.connection.setAutoCommit(true);
+ }
+
+ try {
+ preparedStatement.close();
+ } catch (final Exception e) {
+ }
+
+ closeConnection(openedConnection);
+ }
+
+ /**
+ * Check if connected to the database.
+ *
+ * @return <code>true</code> if connected
+ */
+ public boolean isConnected() {
+ return this.isConnected;
+ }
+
+ /**
+ * True if conditions system is frozen
+ *
+ * @return <code>true</code> if conditions system is currently frozen
+ */
+ public boolean isFrozen() {
+ return this.isFrozen;
+ }
+
+ /**
+ * True if conditions manager is properly initialized.
+ *
+ * @return <code>true</code> if the manager is initialized
+ */
+ public boolean isInitialized() {
+ return this.isInitialized;
+ }
+
+ /**
+ * Return <code>true</code> if Test Run configuration is active
+ *
+ * @return <code>true</code> if Test Run configuration is active
+ */
+ public boolean isTestRun() {
+ return this.isTestRun;
+ }
+
+ /**
+ * Load configuration information from an XML document.
+ *
+ * @param document the XML document
+ */
+ private void loadConfiguration(final Document document) {
+
+ final Element node = document.getRootElement().getChild("configuration");
+
+ if (node == null) {
+ return;
+ }
+
+ Element element = node.getChild("setupSvtDetector");
+ if (element != null) {
+ this.setupSvtDetector = Boolean.parseBoolean(element.getText());
+ logger.config("setupSvtDetector = " + this.setupSvtDetector);
+ }
+
+ element = node.getChild("ecalName");
+ if (element != null) {
+ setEcalName(element.getText());
+ }
+
+ element = node.getChild("svtName");
+ if (element != null) {
+ setSvtName(element.getText());
+ }
+
+ element = node.getChild("freezeAfterInitialize");
+ if (element != null) {
+ this.freezeAfterInitialize = Boolean.parseBoolean(element.getText());
+ logger.config("freezeAfterInitialize = " + this.freezeAfterInitialize);
+ }
+
+ element = node.getChild("cacheAllCondition");
+ if (element != null) {
+ this.cacheAllConditions = Boolean.parseBoolean(element.getText());
+ logger.config("cacheAllConditions = " + this.cacheAllConditions);
+ }
+
+ element = node.getChild("isTestRun");
+ if (element != null) {
+ this.isTestRun = Boolean.parseBoolean(element.getText());
+ logger.config("isTestRun = " + this.isTestRun);
+ }
+
+ element = node.getChild("logLevel");
+ if (element != null) {
+ setLogLevel(Level.parse(element.getText()));
+ }
+
+ element = node.getChild("closeConnectionAfterInitialize");
+ if (element != null) {
+ this.closeConnectionAfterInitialize = Boolean.parseBoolean(element.getText());
+ logger.config("closeConnectionAfterInitialize = " + this.closeConnectionAfterInitialize);
+ }
+
+ element = node.getChild("loginTimeout");
+ if (element != null) {
+ final Integer timeout = Integer.parseInt(element.getText());
+ DriverManager.setLoginTimeout(timeout);
+ logger.config("loginTimeout = " + timeout);
+ }
}
/**
@@ -1013,47 +865,197 @@
// If there is a tag set but the record has no tag, it is rejected.
return false;
}
- return tag.equals(recordTag);
- }
-
- /**
- * Cache conditions sets for all known tables.
- */
- private void cacheConditionsSets() {
- for (TableMetaData meta : tableRegistry.values()) {
- try {
- logger.fine("caching conditions " + meta.getKey() + " with type " + meta.getCollectionClass().getCanonicalName());
- getCachedConditions(meta.getCollectionClass(), meta.getKey());
- } catch (Exception e) {
- logger.warning("could not cache conditions " + meta.getKey());
- }
- }
- }
-
- /**
- * Configure this class from an <code>InputStream</code> which should point to an XML document.
- *
- * @param in the InputStream which should be in XML format
- */
- private void configure(final InputStream in) {
- if (!isConfigured) {
- final SAXBuilder builder = new SAXBuilder();
- Document config = null;
- try {
- config = builder.build(in);
- } catch (JDOMException | IOException e) {
- throw new RuntimeException(e);
- }
- loadConfiguration(config);
- try {
- in.close();
- } catch (IOException e) {
- logger.warning(e.getMessage());
- }
- isConfigured = true;
+ return this.tag.equals(recordTag);
+ }
+
+ /**
+ * Open the database connection.
+ *
+ * @return <code>true</code> if a connection was opened; <code>false</code> if using an existing connection.
+ */
+ public synchronized boolean openConnection() {
+ boolean openedConnection = false;
+ if (!this.isConnected) {
+ // Do the connection parameters need to be figured out automatically?
+ if (this.connectionParameters == null) {
+ // Setup the default read-only connection, which will choose a SLAC or JLab database.
+ this.connectionParameters = ConnectionParameters.fromResource(DEFAULT_CONNECTION_PROPERTIES_RESOURCE);
+ }
+
+ if (!this.loggedConnectionParameters) {
+ // Print out detailed info to the log on first connection within the job.
+ logger.info("opening connection ... " + '\n' + "connection: "
+ + this.connectionParameters.getConnectionString() + '\n' + "host: "
+ + this.connectionParameters.getHostname() + '\n' + "port: "
+ + this.connectionParameters.getPort() + '\n' + "user: " + this.connectionParameters.getUser()
+ + '\n' + "database: " + this.connectionParameters.getDatabase());
+ this.loggedConnectionParameters = true;
+ }
+
+ // Create the connection using the parameters.
+ this.connection = this.connectionParameters.createConnection();
+ this.isConnected = true;
+ openedConnection = true;
+ }
+ logger.info("connection opened successfully");
+
+ // Flag to indicate whether an existing connection was used or not.
+ return openedConnection;
+ }
+
+ /**
+ * Register the conditions converters with the manager.
+ */
+ private void registerConverters() {
+ if (this.svtConverter != null) {
+ // Remove old SVT converter.
+ removeConditionsConverter(this.svtConverter);
+ }
+
+ if (this.ecalConverter != null) {
+ // Remove old ECAL converter.
+ registerConditionsConverter(this.ecalConverter);
+ }
+
+ // Is configured for TestRun?
+ if (isTestRun()) {
+ // Load Test Run specific converters.
+ this.svtConverter = new TestRunSvtConditionsConverter();
+ this.ecalConverter = new TestRunEcalConditionsConverter();
+ logger.config("registering Test Run conditions converters");
} else {
- logger.warning("System is already configured, so call to configure is ignored!");
- }
+ // Load the default converters.
+ this.svtConverter = new SvtConditionsConverter();
+ this.ecalConverter = new EcalConditionsConverter();
+ logger.config("registering default conditions converters");
+ }
+ registerConditionsConverter(this.svtConverter);
+ registerConditionsConverter(this.ecalConverter);
+ }
+
+ /**
+ * This method can be used to perform a database SELECT query.
+ *
+ * @param query the SQL query string
+ * @return the <code>ResultSet</code> from the query
+ * @throws RuntimeException if there is a query error
+ */
+ ResultSet selectQuery(final String query) {
+ logger.fine("executing SQL select query ..." + '\n' + query);
+ ResultSet result = null;
+ Statement statement = null;
+ try {
+ statement = this.connection.createStatement();
+ result = statement.executeQuery(query);
+ } catch (final SQLException x) {
+ throw new RuntimeException("Error in query: " + query, x);
+ }
+ return result;
+ }
+
+ /**
+ * Set the connection parameters of the conditions database.
+ *
+ * @param connectionParameters the connection parameters
+ */
+ public void setConnectionParameters(final ConnectionParameters connectionParameters) {
+ this.connectionParameters = connectionParameters;
+ }
+
+ /**
+ * Set the path to a properties file containing connection settings.
+ *
+ * @param file the properties file
+ */
+ public void setConnectionProperties(final File file) {
+ logger.config("setting connection properties file " + file.getPath());
+ if (!file.exists()) {
+ throw new IllegalArgumentException("The connection properties file does not exist: "
+ + this.connectionPropertiesFile.getPath());
+ }
+ this.connectionParameters = ConnectionParameters.fromProperties(file);
+ }
+
+ /**
+ * Set the connection parameters from an embedded resource location.
+ *
+ * @param resource the classpath resource location
+ */
+ public void setConnectionResource(final String resource) {
+ logger.config("setting connection resource " + resource);
+ this.connectionParameters = ConnectionParameters.fromResource(resource);
+ }
+
+ /**
+ * This method handles changes to the detector name and run number. It is called every time an LCSim event is
+ * created, and so it has internal logic to figure out if the conditions system actually needs to be updated.
+ */
+ @Override
+ public synchronized void setDetector(final String detectorName, final int runNumber)
+ throws ConditionsNotFoundException {
+
+ logger.finest("setDetector " + detectorName + " with run number " + runNumber);
+
+ if (detectorName == null) {
+ throw new IllegalArgumentException("The detectorName argument is null.");
+ }
+
+ if (!this.isInitialized || !detectorName.equals(getDetector()) || runNumber != getRun()) {
+ if (!this.isFrozen) {
+ logger.info("new detector " + detectorName + " and run #" + runNumber);
+ initialize(detectorName, runNumber);
+ } else {
+ logger.finest("Conditions changed but will be ignored because manager is frozen.");
+ }
+ }
+ }
+
+ /**
+ * Set the name of the ECAL sub-detector.
+ *
+ * @param ecalName the name of the ECAL subdetector
+ */
+ private void setEcalName(final String ecalName) {
+ if (ecalName == null) {
+ throw new IllegalArgumentException("The ecalName is null");
+ }
+ this.ecalName = ecalName;
+ logger.info("ECAL name set to " + ecalName);
+ }
+
+ /**
+ * Set the log level.
+ *
+ * @param level the new log level
+ */
+ public void setLogLevel(final Level level) {
+ logger.config("setting log level to " + level);
+ logger.setLevel(level);
+ logger.getHandlers()[0].setLevel(level);
+ this.svtSetup.setLogLevel(level);
+ }
+
+ /**
+ * Set the name of the SVT subdetector.
+ *
+ * @param svtName the name of the SVT subdetector
+ */
+ private void setSvtName(final String svtName) {
+ if (svtName == null) {
+ throw new IllegalArgumentException("The svtName is null");
+ }
+ this.svtName = svtName;
+ logger.info("SVT name set to " + this.ecalName);
+ }
+
+ /**
+ * Set a tag used to filter the accessible conditions records
+ *
+ * @param tag the tag value used to filter returned conditions records
+ */
+ public void setTag(final String tag) {
+ this.tag = tag;
+ logger.info("using conditions tag: " + tag);
}
/**
@@ -1075,68 +1077,66 @@
}
/**
- * Load configuration information from an XML document.
- *
- * @param document the XML document
- */
- private void loadConfiguration(final Document document) {
-
- final Element node = document.getRootElement().getChild("configuration");
-
- if (node == null) {
- return;
- }
-
- Element element = node.getChild("setupSvtDetector");
- if (element != null) {
- setupSvtDetector = Boolean.parseBoolean(element.getText());
- logger.config("setupSvtDetector = " + setupSvtDetector);
- }
-
- element = node.getChild("ecalName");
- if (element != null) {
- setEcalName(element.getText());
- }
-
- element = node.getChild("svtName");
- if (element != null) {
- setSvtName(element.getText());
- }
-
- element = node.getChild("freezeAfterInitialize");
- if (element != null) {
- freezeAfterInitialize = Boolean.parseBoolean(element.getText());
- logger.config("freezeAfterInitialize = " + freezeAfterInitialize);
- }
-
- element = node.getChild("cacheAllCondition");
- if (element != null) {
- cacheAllConditions = Boolean.parseBoolean(element.getText());
- logger.config("cacheAllConditions = " + cacheAllConditions);
- }
-
- element = node.getChild("isTestRun");
- if (element != null) {
- isTestRun = Boolean.parseBoolean(element.getText());
- logger.config("isTestRun = " + isTestRun);
- }
-
- element = node.getChild("logLevel");
- if (element != null) {
- setLogLevel(Level.parse(element.getText()));
- }
-
- element = node.getChild("closeConnectionAfterInitialize");
- if (element != null) {
- closeConnectionAfterInitialize = Boolean.parseBoolean(element.getText());
- logger.config("closeConnectionAfterInitialize = " + closeConnectionAfterInitialize);
- }
-
- element = node.getChild("loginTimeout");
- if (element != null) {
- final Integer timeout = Integer.parseInt(element.getText());
- DriverManager.setLoginTimeout(timeout);
- logger.config("loginTimeout = " + timeout);
- }
+ * Configure some properties of this object from an XML file
+ *
+ * @param file the XML file
+ */
+ public void setXmlConfig(final File file) {
+ logger.config("setting XML config from file " + file.getPath());
+ if (!file.exists()) {
+ throw new IllegalArgumentException("The config file does not exist: " + file.getPath());
+ }
+ try {
+ configure(new FileInputStream(file));
+ } catch (final FileNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Configure this object from an embedded XML resource.
+ *
+ * @param resource the embedded XML resource
+ */
+ public void setXmlConfig(final String resource) {
+ logger.config("setting XML config from resource " + resource);
+ final InputStream is = getClass().getResourceAsStream(resource);
+ configure(is);
+ }
+
+ /**
+ * Un-freeze the conditions system so that updates will be received again.
+ */
+ public synchronized void unfreeze() {
+ this.isFrozen = false;
+ logger.info("conditions system unfrozen");
+ }
+
+ /**
+ * Perform a SQL query with an update command like INSERT, DELETE or UPDATE.
+ *
+ * @param query the SQL query string
+ * @return the keys of the rows affected
+ */
+ public List<Integer> updateQuery(final String query) {
+ final boolean openedConnection = openConnection();
+ logger.fine("executing SQL update query ..." + '\n' + query);
+ final List<Integer> keys = new ArrayList<Integer>();
+ Statement statement = null;
+ ResultSet resultSet = null;
+ try {
+ statement = this.connection.createStatement();
+ statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
+ resultSet = statement.getGeneratedKeys();
+ while (resultSet.next()) {
+ final int key = resultSet.getInt(1);
+ keys.add(key);
+ }
+ } catch (final SQLException x) {
+ throw new RuntimeException("Error in SQL query: " + query, x);
+ }
+ DatabaseUtilities.cleanup(resultSet);
+ closeConnection(openedConnection);
+ return keys;
}
}
Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/QueryBuilder.java
=============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/QueryBuilder.java (original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/QueryBuilder.java Wed Apr 15 14:29:14 2015
@@ -5,6 +5,7 @@
import java.util.List;
import org.hps.conditions.api.ConditionsObject;
+import org.hps.conditions.api.ConditionsRecord;
import org.hps.conditions.api.FieldValueMap;
/**
@@ -15,13 +16,119 @@
public final class QueryBuilder {
/**
- * Dot not allow instantiation.
+ * Date formatting for insert statement.
*/
- private QueryBuilder() {
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
+
+ /**
+ * Build an insert statement.
+ *
+ * @param tableName the table name
+ * @param fieldValues the field values
+ * @return the insert statement
+ */
+ public static String buildInsert(final String tableName, final FieldValueMap fieldValues) {
+ if (fieldValues.size() == 0) {
+ throw new IllegalArgumentException("The FieldValueMap has no values.");
+ }
+ final StringBuffer sb = new StringBuffer();
+ sb.append("INSERT INTO " + tableName + " (");
+ for (final String fieldName : fieldValues.keySet()) {
+ sb.append(" " + fieldName + ",");
+ }
+ sb.setLength(sb.length() - 1);
+ sb.append(" ) VALUES (");
+ for (final Object value : fieldValues.values()) {
+ final String insertValue = value.toString();
+ if (value instanceof Date) {
+ sb.append(" STR_TO_DATE( '" + DATE_FORMAT.format((Date) value) + "', '%Y-%m-%d %H:%i:%S' ),");
+ } else {
+ sb.append(" '" + insertValue + "',");
+ }
+ }
+ sb.setLength(sb.length() - 1);
+ sb.append(")");
+ return sb.toString();
+ }
+
+ /*
+ * static String buildUpdate(String tableName, int rowId, String[] fields, Object[] values) { if (fields.length !=
+ * values.length) throw new IllegalArgumentException("The field and value arrays are different lengths.");
+ * StringBuffer buff = new StringBuffer(); buff.append("UPDATE " + tableName + " SET "); for (int i = 0; i <
+ * fields.length; i++) { buff.append(fields[i] + " = '" + values[i] + "', "); } buff.delete(buff.length() - 2,
+ * buff.length() - 1); buff.append(" WHERE id = " + rowId); return buff.toString(); } public static String
+ * buildInsert(String tableName, int collectionId, String[] fields, Object[] values) { if (fields.length !=
+ * values.length) throw new IllegalArgumentException("The field and value arrays are different lengths.");
+ * StringBuffer buff = new StringBuffer(); buff.append("INSERT INTO " + tableName + "( collection_id"); for (String
+ * field : fields) { buff.append(", " + field); } buff.append(" ) VALUES ( " + collectionId); for (Object value :
+ * values) { buff.append(", " + value); } buff.append(") "); return buff.toString(); }
+ */
+
+ /**
+ * Build a SQL insert statement.
+ *
+ * @param tableName the table name
+ * @param collectionID the collection ID
+ * @param columnNames the column names
+ * @param rows the row data
+ * @return the SQL insert statement
+ */
+ public static String buildInsert(final String tableName, final int collectionID, final List<String> columnNames,
+ final List<List<String>> rows) {
+ final StringBuffer buff = new StringBuffer();
+ buff.append("INSERT INTO " + tableName + " ( collection_id");
+ for (final String column : columnNames) {
+ buff.append(", " + column);
+ }
+ buff.append(" ) VALUES ");
+ for (final List<String> values : rows) {
+ buff.append("( ");
+ buff.append(collectionID);
+ for (final String value : values) {
+ buff.append(", '" + value + "'");
+ }
+ buff.append("), ");
+ }
+ buff.setLength(buff.length() - 2);
+ return buff.toString();
+ }
+
+ /**
+ * Build a prepared insert statement for a conditions object.
+ *
+ * @param tableName the name of the table
+ * @param object the conditions object
+ * @return the prepared insert statement
+ */
+ static String buildPreparedInsert(final String tableName, final ConditionsObject object) {
+ if (object.getFieldValues().size() == 0) {
+ throw new IllegalArgumentException("The ConditionsObject has no values set.");
+ }
+ final StringBuffer buffer = new StringBuffer();
+ buffer.append("INSERT INTO " + tableName + "( ");
+ // FIXME: Hack for specific type.
+ if (!(object instanceof ConditionsRecord)) {
+ buffer.append("collection_id,");
+ }
+ for (final String fieldName : object.getFieldValues().keySet()) {
+ buffer.append(" " + fieldName + ",");
+ }
+ buffer.setLength(buffer.length() - 1);
+ buffer.append(" ) VALUES ( ");
+ if (!(object instanceof ConditionsRecord)) {
+ buffer.append(" ?,");
+ }
+ for (int i = 0; i < object.getFieldValues().size(); i++) {
+ buffer.append(" ?,");
+ }
+ buffer.setLength(buffer.length() - 1);
+ buffer.append(")");
+ return buffer.toString();
}
/**
* Build a SQL select query string.
+ *
* @param tableName the name of the table
* @param collectionId the collection ID
* @param fields the list of fields
@@ -37,7 +144,7 @@
} else {
// Always implicitly include the row ID.
buff.append("id, ");
- for (String fieldName : fields) {
+ for (final String fieldName : fields) {
buff.append(fieldName + ", ");
}
buff.delete(buff.length() - 2, buff.length() - 1);
@@ -52,140 +159,25 @@
return buff.toString();
}
- /*
- static String buildUpdate(String tableName, int rowId, String[] fields, Object[] values) {
- if (fields.length != values.length)
- throw new IllegalArgumentException("The field and value arrays are different lengths.");
- StringBuffer buff = new StringBuffer();
- buff.append("UPDATE " + tableName + " SET ");
- for (int i = 0; i < fields.length; i++) {
- buff.append(fields[i] + " = '" + values[i] + "', ");
- }
- buff.delete(buff.length() - 2, buff.length() - 1);
- buff.append(" WHERE id = " + rowId);
- return buff.toString();
- }
-
- public static String buildInsert(String tableName, int collectionId, String[] fields, Object[] values) {
- if (fields.length != values.length)
- throw new IllegalArgumentException("The field and value arrays are different lengths.");
- StringBuffer buff = new StringBuffer();
- buff.append("INSERT INTO " + tableName + "( collection_id");
- for (String field : fields) {
- buff.append(", " + field);
- }
- buff.append(" ) VALUES ( " + collectionId);
- for (Object value : values) {
- buff.append(", " + value);
- }
- buff.append(") ");
- return buff.toString();
- }
- */
-
- /**
- * Build a prepared insert statement for a conditions object.
- * @param tableName the name of the table
- * @param object the conditions object
- * @return the prepared insert statement
- */
- static String buildPreparedInsert(final String tableName, final ConditionsObject object) {
- if (object.getFieldValues().size() == 0) {
- throw new IllegalArgumentException("The ConditionsObject has no values set.");
- }
- final StringBuffer buffer = new StringBuffer();
- buffer.append("INSERT INTO " + tableName + "( collection_id, ");
- for (String fieldName : object.getFieldValues().keySet()) {
- buffer.append(" " + fieldName + ",");
- }
- buffer.setLength(buffer.length() - 1);
- buffer.append(" ) VALUES ( ?,");
- for (Object value : object.getFieldValues().values()) {
- buffer.append(" ?,");
- }
- buffer.setLength(buffer.length() - 1);
- buffer.append(")");
- return buffer.toString();
- }
-
- /**
- * Date formatting for insert statement.
- */
- private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
-
- /**
- * Build an insert statement.
- * @param tableName the table name
- * @param fieldValues the field values
- * @return the insert statement
- */
- public static String buildInsert(final String tableName, final FieldValueMap fieldValues) {
- if (fieldValues.size() == 0) {
- throw new IllegalArgumentException("The FieldValueMap has no values.");
- }
- final StringBuffer sb = new StringBuffer();
- sb.append("INSERT INTO " + tableName + " (");
- for (String fieldName : fieldValues.keySet()) {
- sb.append(" " + fieldName + ",");
- }
- sb.setLength(sb.length() - 1);
- sb.append(" ) VALUES (");
- for (Object value : fieldValues.values()) {
- final String insertValue = value.toString();
- if (value instanceof Date) {
- sb.append(" STR_TO_DATE( '" + DATE_FORMAT.format((Date) value) + "', '%Y-%m-%d %H:%i:%S' ),");
- } else {
- sb.append(" '" + insertValue + "',");
- }
- }
- sb.setLength(sb.length() - 1);
- sb.append(")");
- return sb.toString();
- }
-
- /**
- * Build a SQL insert statement.
- * @param tableName the table name
- * @param collectionID the collection ID
- * @param columnNames the column names
- * @param rows the row data
- * @return the SQL insert statement
- */
- public static String buildInsert(final String tableName, final int collectionID,
- final List<String> columnNames, final List<List<String>> rows) {
- final StringBuffer buff = new StringBuffer();
- buff.append("INSERT INTO " + tableName + " ( collection_id");
- for (String column : columnNames) {
- buff.append(", " + column);
- }
- buff.append(" ) VALUES ");
- for (List<String> values : rows) {
- buff.append("( ");
- buff.append(collectionID);
- for (String value : values) {
- buff.append(", '" + value + "'");
- }
- buff.append("), ");
- }
- buff.setLength(buff.length() - 2);
- return buff.toString();
- }
-
- /*
- static String buildDelete(String tableName, int rowId) {
- if (rowId <= 0)
- throw new IllegalArgumentException("Invalid row ID: " + rowId);
- String query = "DELETE FROM " + tableName + " WHERE id = " + rowId;
- return query;
- }
- */
-
/**
* Format the date for insert statement.
+ *
* @param date the input date
* @return the formatted date string
*/
static String formatDate(final Date date) {
return DATE_FORMAT.format(date);
}
+
+ /*
+ * static String buildDelete(String tableName, int rowId) { if (rowId <= 0) throw new
+ * IllegalArgumentException("Invalid row ID: " + rowId); String query = "DELETE FROM " + tableName + " WHERE id = "
+ * + rowId; return query; }
+ */
+
+ /**
+ * Dot not allow instantiation.
+ */
+ private QueryBuilder() {
+ }
}
|