Author: [log in to unmask] Date: Fri Sep 4 12:59:35 2015 New Revision: 3524 Log: Merge in conditions branch to trunk. HPSJAVA-517 Added: java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsTag.java - copied unchanged from r3393, java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/ConditionsTag.java java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java - copied unchanged from r3393, java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java java/trunk/conditions/src/test/java/org/hps/conditions/api/ConditionsTagTest.java - copied, changed from r3393, java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/api/ConditionsTagTest.java Modified: java/trunk/conditions/ (props changed) java/trunk/conditions/pom.xml java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java java/trunk/conditions/src/main/java/org/hps/conditions/api/TableMetaData.java java/trunk/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java java/trunk/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java java/trunk/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java java/trunk/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java java/trunk/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java java/trunk/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java java/trunk/evio/src/main/java/org/hps/evio/EvioToLcio.java Modified: java/trunk/conditions/pom.xml ============================================================================= --- java/trunk/conditions/pom.xml (original) +++ java/trunk/conditions/pom.xml Fri Sep 4 12:59:35 2015 @@ -32,12 +32,14 @@ <exclude>org/hps/conditions/svt/SvtDetectorSetupTest.java</exclude> <exclude>org/hps/conditions/svt/SvtConfigurationTest.java</exclude> <exclude>org/hps/conditions/svt/SvtDaqMappingTest.java</exclude> + <exclude>org/hps/conditions/svt/TestRunSvtBadChannelsTest.java</exclude> <exclude>org/hps/conditions/svt/TestRunSvtConditionsConverterTest.java</exclude> <exclude>org/hps/conditions/svt/TestRunSvtDaqMappingTest.java</exclude> <exclude>org/hps/conditions/beam/BeamConditionsTest.java</exclude> <exclude>org/hps/conditions/ecal/EcalHardwareConditionsTest.java</exclude> <exclude>org/hps/conditions/database/CollectionIdTest.java</exclude> <exclude>org/hps/conditions/svt/SvtTimingConstantsTest.java</exclude> + <exclude>org/hps/conditions/api/ConditionsTagTest.java</exclude> <exclude>org/hps/conditions/dummy/**.java</exclude> </excludes> </configuration> Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java Fri Sep 4 12:59:35 2015 @@ -75,7 +75,7 @@ if (this.tag != null) { // Set a tag for filtering ConditionsRecord objects. - conditionsManager.setTag(this.tag); + conditionsManager.addTag(this.tag); } if (this.detectorName != null) { // The manager can only be initialized here if there is a user supplied detector name. Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java Fri Sep 4 12:59:35 2015 @@ -358,9 +358,11 @@ /** * Get the string tag associated with these conditions. * + * @deprecated Use the {@link ConditionsTag} class instead. * @return The string tag. */ @Field(names = {"tag"}) + @Deprecated public String getTag() { return this.getFieldValue("tag"); } Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/TableMetaData.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/api/TableMetaData.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/api/TableMetaData.java Fri Sep 4 12:59:35 2015 @@ -262,9 +262,16 @@ buff.append('\n'); return buff.toString(); } - - // TODO: add methods for getting SQL strings for PreparedStatements; can be setup once at initialization time for - // each table + + /** + * Method for removing a field that was found using the automatic introspection methods. + */ + void removeField(String fieldName) { + fieldNames.remove(fieldName); + fieldTypes.remove(fieldName); + } + + // TODO: add methods for getting SQL strings for PreparedStatements; can be setup once at initialization time for each table // String getSelectStatement(); // String getInsertStatement(); // String getUpdateStatement(); Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java Fri Sep 4 12:59:35 2015 @@ -6,6 +6,7 @@ import org.apache.commons.cli.ParseException; import org.apache.commons.cli.Parser; import org.apache.commons.cli.PosixParser; +import org.hps.conditions.database.DatabaseConditionsManager; /** * This is the API that sub-commands such as 'load' or 'print' must implement in the conditions command line interface. @@ -108,4 +109,12 @@ final HelpFormatter help = new HelpFormatter(); help.printHelp(this.getName(), this.getOptions()); } + + /** + * Convenience method for getting the conditions manager. + * @return the conditions manager + */ + public DatabaseConditionsManager getManager() { + return DatabaseConditionsManager.getInstance(); + } } Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java Fri Sep 4 12:59:35 2015 @@ -41,7 +41,6 @@ OPTIONS.getOption("t").setRequired(true); OPTIONS.addOption("c", true, "collection ID (required)"); OPTIONS.getOption("c").setRequired(true); - OPTIONS.addOption("T", true, "tag value (optional)"); OPTIONS.addOption("u", true, "user name (optional)"); OPTIONS.addOption("m", true, "notes about this conditions set (optional)"); } @@ -67,7 +66,7 @@ * @return the new conditions record */ private ConditionsRecord createConditionsRecord(final int runStart, final int runEnd, final String tableName, - final String name, final int collectionId, final String createdBy, final String tag, final String notes) { + final String name, final int collectionId, final String createdBy, final String notes) { final ConditionsRecord conditionsRecord = new ConditionsRecord(); final FieldValuesMap fieldValues = new FieldValuesMap(); fieldValues.setValue("run_start", runStart); @@ -76,9 +75,6 @@ fieldValues.setValue("name", name); fieldValues.setValue("collection_id", collectionId); fieldValues.setValue("created_by", createdBy); - if (tag != null) { - fieldValues.setValue("tag", tag); - } if (notes != null) { fieldValues.setValue("notes", notes); } @@ -134,12 +130,6 @@ createdBy = commandLine.getOptionValue("u"); } - // Tag to assign (optional). - String tag = null; - if (commandLine.hasOption("T")) { - tag = commandLine.getOptionValue("T"); - } - // Notes (optional). String notes = null; if (commandLine.hasOption("m")) { @@ -148,7 +138,7 @@ // Create the conditions record to insert. final ConditionsRecord conditionsRecord = this.createConditionsRecord(runStart, runEnd, tableName, name, - collectionId, createdBy, tag, notes); + collectionId, createdBy, notes); LOGGER.info("inserting conditions record ..." + '\n' + conditionsRecord); try { boolean createdConnection = false; Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java Fri Sep 4 12:59:35 2015 @@ -202,7 +202,7 @@ // User specified tag of conditions records. if (commandLine.hasOption("t")) { final String tag = commandLine.getOptionValue("t"); - this.conditionsManager.setTag(tag); + this.conditionsManager.addTag(tag); LOGGER.config("using tag " + tag); } Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java Fri Sep 4 12:59:35 2015 @@ -1,9 +1,9 @@ package org.hps.conditions.cli; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -12,54 +12,81 @@ import org.apache.commons.cli.Options; import org.hps.conditions.api.ConditionsObjectException; import org.hps.conditions.api.ConditionsRecord; -import org.hps.conditions.api.TableRegistry; import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection; +import org.hps.conditions.api.ConditionsTag; +import org.hps.conditions.api.ConditionsTag.ConditionsTagCollection; import org.hps.conditions.api.DatabaseObjectException; import org.hps.conditions.api.TableMetaData; -import org.hps.conditions.database.DatabaseConditionsManager; -import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException; +import org.hps.conditions.api.TableRegistry; +import org.hps.conditions.database.MultipleCollectionsAction; +import org.lcsim.util.log.DefaultLogFormatter; import org.lcsim.util.log.LogUtil; /** * Create a conditions system tag. + * <p> + * The tag groups together conditions records from the <i>conditions</i> database table with a run validity range that + * is between a specified starting and ending run. + * <p> + * Tagging will not disambiguate overlapping conditions, which is done at run-time based on the current run number. * * @author Jeremy McCormick, SLAC */ -public class TagCommand extends AbstractCommand { - - /** - * The default detector name (dummy detector). - */ - private static final String DETECTOR_NAME = "HPS-dummy-detector"; - - /** - * Setup logger. - */ - private static final Logger LOGGER = LogUtil.create(TagCommand.class); - +final class TagCommand extends AbstractCommand { + + /** + * Setup the logger. + */ + private static final Logger LOGGER = LogUtil.create(TagCommand.class, new DefaultLogFormatter(), Level.ALL); + /** * Defines command options. */ private static Options OPTIONS = new Options(); /** - * Define command options. + * Define all command options. */ static { OPTIONS.addOption(new Option("h", false, "Show help for tag command")); - OPTIONS.addOption(new Option("r", true, "List of run numbers to scan (at least one must be provided)")); - OPTIONS.getOption("r").setArgs(Option.UNLIMITED_VALUES); - OPTIONS.getOption("r").setRequired(true); - OPTIONS.addOption(new Option("t", true, "The new conditions tag")); + OPTIONS.addOption(new Option("t", true, "Conditions tag name")); + OPTIONS.addOption(new Option("s", true, "Starting run number (required)")); + OPTIONS.getOption("s").setRequired(true); + OPTIONS.addOption(new Option("e", true, "Ending run number (default is unlimited)")); OPTIONS.getOption("t").setRequired(true); - OPTIONS.addOption(new Option("f", false, "Don't prompt before making tag (careful!)")); + OPTIONS.addOption(new Option("m", true, + "MultipleCollectionsAction to use for disambiguation (default is LAST_CREATED)")); + OPTIONS.addOption(new Option("d", false, "Don't prompt before making tag (be careful!)")); } /** * Class constructor. */ TagCommand() { - super("tag", "Tag a set of collections by copying their conditions records", OPTIONS); + super("tag", "Tag a set of conditions records to group them together", OPTIONS); + } + + /** + * Create the collection with the records for creating a new conditions "tag". + * + * @param tagConditionsRecordCollection the tag record collection + * @param tagName the tag name + * @return the tag record collection + */ + private ConditionsTagCollection createConditionsTagCollection( + final ConditionsRecordCollection tagConditionsRecordCollection, final String tagName) { + final ConditionsTagCollection conditionsTagCollection = new ConditionsTagCollection(); + conditionsTagCollection.setConnection(this.getManager().getConnection()); + conditionsTagCollection.setTableMetaData(TableRegistry.getTableRegistry().findByTableName("conditions_tags")); + for (final ConditionsRecord conditionsRecord : tagConditionsRecordCollection) { + final ConditionsTag conditionsTag = new ConditionsTag(conditionsRecord.getRowId(), tagName); + try { + conditionsTagCollection.add(conditionsTag); + } catch (final ConditionsObjectException e) { + throw new RuntimeException(e); + } + } + return conditionsTagCollection; } /** @@ -70,108 +97,154 @@ final CommandLine commandLine = this.parse(arguments); - final Set<Integer> runNumbers = new LinkedHashSet<Integer>(); - if (commandLine.getOptionValues("r") == null) { - throw new RuntimeException("Missing -r argument with list of run numbers."); - } - for (final String value : commandLine.getOptionValues("r")) { - runNumbers.add(Integer.parseInt(value)); - } - if (runNumbers.size() == 0) { - throw new RuntimeException("At least one run number must be provided with the -r switch."); - } - - final String newTag; + // New tag name. + final String tagName; if (commandLine.hasOption("t")) { - newTag = commandLine.getOptionValue("t"); + tagName = commandLine.getOptionValue("t"); + LOGGER.info("tag name set to " + tagName); } else { throw new RuntimeException("Missing required -t argument with the tag name."); } - boolean dontPrompt = false; - if (commandLine.hasOption("f")) { - dontPrompt = true; - } - - final ConditionsRecordCollection tagRecords = new ConditionsRecordCollection(); - final Set<Integer> addedIds = new HashSet<Integer>(); - - final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance(); - manager.setXmlConfig("/org/hps/conditions/config/conditions_database_no_svt.xml"); - manager.setLogLevel(Level.ALL); - - // Scan through all the runs between the start and end run, inclusive. - for (final Integer run : runNumbers) { - try { - // Setup the conditions manager with the run number. - manager.setDetector(TagCommand.DETECTOR_NAME, run); - } catch (final ConditionsNotFoundException e) { - throw new RuntimeException(e); - } - - // The unique conditions keys from this run. - final Set<String> keys = manager.getConditionsRecords().getConditionsKeys(); - - // Scan through all the unique keys. - for (final String key : keys) { - - // Get the table meta data for the key. - final TableMetaData tableMetaData = manager.findTableMetaData(key); - - // Get the ConditionsRecord from the collection. - final ConditionsRecordCollection records = manager.findConditionsRecords(key); - records.sortByUpdated(); - final ConditionsRecord record = records.get(records.size() - 1); - - manager.getCachedConditions(tableMetaData.getCollectionClass(), tableMetaData.getTableName()) - .getCachedData(); - - // Is this record already part of the new tag? - if (!addedIds.contains(record.getRowId())) { - // Create a new record copied from the old one. - final ConditionsRecord newRecord = new ConditionsRecord(record); - - // Set the tag value. - newRecord.setFieldValue("tag", newTag); - - // Add the record to the tag. - try { - tagRecords.add(newRecord); - } catch (final ConditionsObjectException e) { - throw new RuntimeException(e); - } - - // Flag the record's ID as used so it is only added once. - addedIds.add(record.getRowId()); - } - } - } - - // Print out all the records that were found. - LOGGER.info("found ConditionsRecords for tag " + newTag + " ..."); - for (final ConditionsRecord record : tagRecords) { - LOGGER.info(record.toString()); - } - - // Prompt user to verify with console input. - boolean makeTag = true; - if (!dontPrompt) { - LOGGER.info("Create conditions tag " + newTag + " in database? (Y/N)"); + // Starting run number (required). + int runStart = -1; + if (commandLine.hasOption("s")) { + runStart = Integer.parseInt(commandLine.getOptionValue("s")); + LOGGER.config("run start set to " + runStart); + } else { + throw new RuntimeException("missing require -s argument with starting run number"); + } + + // Ending run number (max integer is default). + int runEnd = Integer.MAX_VALUE; + if (commandLine.hasOption("e")) { + runEnd = Integer.parseInt(commandLine.getOptionValue("e")); + LOGGER.config("run end set to " + runEnd); + } + + // Run end must be greater than or equal to run start. + if (runEnd < runStart) { + throw new IllegalArgumentException("runEnd < runStart"); + } + + // Action for disambiguating overlapping collections (default is to use the most recent creation date). + MultipleCollectionsAction multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED; + if (commandLine.hasOption("m")) { + multipleCollectionsAction = MultipleCollectionsAction + .valueOf(commandLine.getOptionValue("m").toUpperCase()); + } + LOGGER.config("multiple collections action set tco " + multipleCollectionsAction); + + // Whether to prompt before tagging (default is yes). + boolean promptBeforeTagging = true; + if (commandLine.hasOption("d")) { + promptBeforeTagging = false; + } + LOGGER.config("prompt before tagging: " + promptBeforeTagging); + + // Conditions system configuration. + this.getManager().setXmlConfig("/org/hps/conditions/config/conditions_database_no_svt.xml"); + this.getManager().setLogLevel(Level.ALL); + + // Find all the applicable conditions records by their run number ranges. + ConditionsRecordCollection tagConditionsRecordCollection = this.findConditionsRecords(runStart, runEnd); + + LOGGER.info("found " + tagConditionsRecordCollection.size() + " conditions records for the tag"); + + // Build the collection of tag records to insert into the database. + final ConditionsTagCollection conditionsTagCollection = this.createConditionsTagCollection( + tagConditionsRecordCollection, tagName); + + LOGGER.info("created " + conditionsTagCollection.size() + " tag records ..." + '\n' + conditionsTagCollection); + + LOGGER.getHandlers()[0].flush(); + + // Prompt user to verify tag creation. + boolean createTag = true; + if (promptBeforeTagging) { + System.out.println("Create conditions tag '" + tagName + "' in the database? (Y/N)"); final String line = System.console().readLine(); if (!line.equals("Y")) { - makeTag = false; - } - } - - // Create the tag in the database if user verified or force option was present. - if (makeTag) { + createTag = false; + } + } + + // Create the tag. + if (createTag) { try { - tagRecords.setConnection(manager.getConnection()); - tagRecords.setTableMetaData(TableRegistry.getTableRegistry().findByTableName("conditions")); - tagRecords.insert(); + LOGGER.info("creating tag " + tagName + " in the database ..."); + conditionsTagCollection.insert(); } catch (DatabaseObjectException | SQLException e) { throw new RuntimeException(e); } - } + } else { + LOGGER.warning("user aborted tag operation!"); + } + + LOGGER.info("done!"); + } + + /** + * Find all the conditions records that are applicable for the given run range. + * <p> + * Overlapping run numbers in conditions with the same key are not disambiguated. + * This must be done in the user's job at runtime; usually the most recently created + * conditions record will be used if multiple one's are applicable to the current run. + * + * @param runStart the start run + * @param runEnd the end run (must be greater than or equal to <code>runStart</code>) + * @return the conditions records that fall in the run range + */ + private ConditionsRecordCollection findConditionsRecords(final int runStart, final int runEnd) { + if (runStart > runEnd) { + throw new IllegalArgumentException("runStart > runEnd"); + } + if (runStart < 0) { + throw new IllegalArgumentException("invalid runStart: " + runStart); + } + if (runEnd < 0) { + throw new IllegalArgumentException("invalid runEnd: " + runEnd); + } + final Connection connection = this.getManager().getConnection(); + final ConditionsRecordCollection conditionsRecordCollection = new ConditionsRecordCollection(); + final TableMetaData tableMetaData = TableRegistry.getTableRegistry().findByTableName("conditions"); + PreparedStatement statement = null; + try { + /* + * SQL statement handles 3 cases: + * 1) condition's run_start in range + * 2) condition's run_end in range + * 3) condition's run_start and run_end enclose the range + */ + statement = connection + .prepareStatement("SELECT id FROM conditions WHERE (run_start >= ? and run_start <= ?) or (run_end >= ? and run_end <= ?)" + + " or (run_start <= ? and run_end >= ?)"); + statement.setInt(1, runStart); + statement.setInt(2, runEnd); + statement.setInt(3, runStart); + statement.setInt(4, runEnd); + statement.setInt(5, runStart); + statement.setInt(6, runEnd); + + final ResultSet resultSet = statement.executeQuery(); + while (resultSet.next()) { + final ConditionsRecord record = new ConditionsRecord(); + record.setConnection(connection); + record.setTableMetaData(tableMetaData); + record.select(resultSet.getInt(1)); + conditionsRecordCollection.add(record); + } + } catch (DatabaseObjectException | ConditionsObjectException | SQLException e) { + throw new RuntimeException(e); + } finally { + try { + if (statement != null) { + statement.close(); + } + } catch (final SQLException e) { + e.printStackTrace(); + } + } + return conditionsRecordCollection; } } 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 Fri Sep 4 12:59:35 2015 @@ -12,6 +12,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -21,10 +22,9 @@ import org.hps.conditions.api.AbstractConditionsObjectConverter; 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; +import org.hps.conditions.api.ConditionsTag.ConditionsTagCollection; import org.hps.conditions.api.TableMetaData; import org.hps.conditions.api.TableRegistry; import org.hps.conditions.ecal.EcalConditions; @@ -64,7 +64,12 @@ /** * 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"; + private static final String CONNECTION_PROPERTY_FILE = "org.hps.conditions.connection.file"; + + /** + * Connection property resource. + */ + private static final String CONNECTION_PROPERTY_RESOURCE = "org.hps.conditions.connection.resource"; /** * The default XML config. @@ -255,22 +260,47 @@ private final TableRegistry tableRegistry = TableRegistry.getTableRegistry(); /** - * The currently active conditions tag. - */ - private String tag = null; - + * The currently active conditions tag (empty collection means no tag is active). + */ + private ConditionsTagCollection conditionsTagCollection = new ConditionsTagCollection(); + + /** + * The current set of conditions for the run. + */ + private ConditionsRecordCollection conditionsRecordCollection = null; + + /** + * The currently applied conditions tags. + */ + private Set<String> tags = new HashSet<String>(); + /** * Class constructor. Calling this will automatically register this manager as the global default. */ private DatabaseConditionsManager() { + + // Register detector conditions converter. this.registerConditionsConverter(new DetectorConditionsConverter()); - this.setupConnectionFromSystemProperty(); + + // Setup connection from system property pointing to a file, if it was set. + this.setupConnectionSystemPropertyFile(); + + // Setup connection from system property pointing to a resource, if it was set. + this.setupConnectionSystemPropertyResource(); + + // Register default conditions manager. ConditionsManager.setDefaultConditionsManager(this); + + // Set run to invalid number. this.setRun(-1); + + // Register conditions converters. for (final AbstractConditionsObjectConverter converter : this.converters.values()) { // logger.fine("registering converter for " + converter.getType()); this.registerConditionsConverter(converter); } + + // Add the SVT detector setup object as a listener. this.addConditionsListener(this.svtSetup); } @@ -378,27 +408,7 @@ * @return the set of matching conditions records */ public ConditionsRecordCollection findConditionsRecords(final String name) { - final ConditionsRecordCollection runConditionsRecords = this.getCachedConditions( - ConditionsRecordCollection.class, "conditions").getCachedData(); - logger.fine("searching for conditions with name " + name + " in " + runConditionsRecords.size() + " records"); - final ConditionsRecordCollection foundConditionsRecords = new ConditionsRecordCollection(); - for (final ConditionsRecord record : runConditionsRecords) { - if (record.getName().equals(name)) { - if (this.matchesTag(record)) { - try { - foundConditionsRecords.add(record); - } catch (final ConditionsObjectException e) { - throw new RuntimeException(e); - } - logger.finer("found matching conditions record " + record.getRowId()); - } else { - logger.finer("conditions record " + record.getRowId() + " rejected from non-matching tag " - + record.getTag()); - } - } - } - logger.fine("found " + foundConditionsRecords.size() + " conditions records matching tag " + this.tag); - return foundConditionsRecords; + return getConditionsRecords().findByKey(name); } /** @@ -479,31 +489,30 @@ collection.setCollectionId(collectionId); return collectionId; } - - /** - * Get a list of all the {@link ConditionsRecord} objects. - * - * @return the list of all the {@link ConditionsRecord} objects - */ - // FIXME: This should use a cache that is created during initialization, rather than look these up every time. + + /** + * Get the list of conditions records for the run, filtered by the current set of active tags. + * + * @return the list of conditions records for the run + */ public ConditionsRecordCollection getConditionsRecords() { - logger.finer("getting conditions records ..."); - final ConditionsRecordCollection conditionsRecords = new ConditionsRecordCollection(); - for (final TableMetaData tableMetaData : this.tableRegistry.values()) { - try { - final ConditionsRecordCollection foundConditionsRecords = this.findConditionsRecords(tableMetaData - .getKey()); - logger.finer("found " + foundConditionsRecords.size() + " collections with name " - + tableMetaData.getKey()); - conditionsRecords.addAll(foundConditionsRecords); - } catch (final Exception e) { - e.printStackTrace(); - logger.warning(e.getMessage()); - } - } - logger.finer("found " + conditionsRecords + " conditions records"); - logger.getHandlers()[0].flush(); - return conditionsRecords; + if (this.run == -1 || this.detectorName == null) { + throw new IllegalStateException("Conditions system is not initialized."); + } + // If the collection is null then the new conditions records need to be retrieved from the database. + if (this.conditionsRecordCollection == null) { + + // Get the collection of conditions that are applicable for the current run. + this.conditionsRecordCollection = + this.getCachedConditions(ConditionsRecordCollection.class, "conditions").getCachedData(); + + // If there is one or more tags enabled then filter the collection by the tag names. + if (this.conditionsTagCollection.size() > 0) { + this.conditionsRecordCollection = + this.conditionsTagCollection.filter(this.conditionsRecordCollection); + } + } + return this.conditionsRecordCollection; } /** @@ -671,11 +680,14 @@ // Open the database connection. this.openConnection(); - + + // Reset the conditions records to trigger a re-caching. + this.conditionsRecordCollection = null; + // Call the super class's setDetector method to construct the detector object and activate conditions listeners. logger.fine("activating default conditions manager"); super.setDetector(detectorName, runNumber); - + // Should all conditions sets be cached? if (this.cacheAllConditions) { // Cache the conditions sets of all registered converters. @@ -807,24 +819,11 @@ } /** - * Return <code>true</code> if the conditions record matches the current tag - * - * @param record the conditions record - * @return <code>true</code> if conditions record matches the currently used tag - */ - private boolean matchesTag(final ConditionsRecord record) { - if (this.tag == null) { - // If there is no tag set then all records pass. - return true; - } - final String recordTag = record.getTag(); - if (recordTag == null) { - // If there is a tag set but the record has no tag, it is rejected. - return false; - } - return this.tag.equals(recordTag); - } - + * Create a new collection with the given type. + * + * @param collectionType the collection type + * @return the new collection + */ public <CollectionType extends ConditionsObjectCollection<?>> CollectionType newCollection( final Class<CollectionType> collectionType) { final List<TableMetaData> tableMetaDataList = TableRegistry.getTableRegistry().findByCollectionType( @@ -845,6 +844,13 @@ return collection; } + /** + * Create a new collection with the given type and table name. + * + * @param collectionType the collection type + * @param tableName the table name + * @return the new collection + */ public <CollectionType extends ConditionsObjectCollection<?>> CollectionType newCollection( final Class<CollectionType> collectionType, final String tableName) { final TableMetaData tableMetaData = TableRegistry.getTableRegistry().findByTableName(tableName); @@ -1040,31 +1046,69 @@ } /** - * Set a tag used to filter the accessible conditions records + * Add a tag used to filter the accessible conditions records. + * <p> + * Multiple tags are OR'd together. * * @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); + public void addTag(final String tag) { + if (!this.tags.contains(tag)) { + logger.info("adding tag " + tag); + ConditionsTagCollection addConditionsTagCollection = this.getCachedConditions(ConditionsTagCollection.class, tag).getCachedData(); + logger.info("adding conditions tag " + tag + " with " + conditionsTagCollection.size() + " records"); + this.conditionsTagCollection.addAll(addConditionsTagCollection); + } else { + logger.warning("tag " + tag + " is already added"); + } + } + + /** + * Add one or more tags for filtering records. + * + * @param tags the <code>Set</code> of tags to add + */ + public void addTags(final Set<String> tags) { + for (String tag : tags) { + this.addTag(tag); + } + } + + /** + * Clear the tags used to filter the {@link org.hps.conditons.api.ConditionsRecord}s. + */ + public void clearTags() { + this.tags.clear(); + this.conditionsTagCollection.clear(); } /** * Setup the database connection from a file specified by a Java system property setting. This could be overridden * by subsequent API calls to {@link #setConnectionProperties(File)} or {@link #setConnectionResource(String)}. */ - private void setupConnectionFromSystemProperty() { - final String systemPropertiesConnectionPath = (String) System.getProperties().get(CONNECTION_PROPERTY); + private void setupConnectionSystemPropertyFile() { + final String systemPropertiesConnectionPath = (String) System.getProperties().get(CONNECTION_PROPERTY_FILE); if (systemPropertiesConnectionPath != null) { final File f = new File(systemPropertiesConnectionPath); if (!f.exists()) { - throw new RuntimeException("Connection properties file from " + CONNECTION_PROPERTY + throw new RuntimeException("Connection properties file from " + CONNECTION_PROPERTY_FILE + " does not exist."); } this.setConnectionProperties(f); - logger.info("connection setup from system property " + CONNECTION_PROPERTY + " = " + logger.info("connection setup from system property " + CONNECTION_PROPERTY_FILE + " = " + systemPropertiesConnectionPath); - } + } + } + + /** + * Setup the database connection from a file specified by a Java system property setting. This could be overridden + * by subsequent API calls to {@link #setConnectionProperties(File)} or {@link #setConnectionResource(String)}. + */ + private void setupConnectionSystemPropertyResource() { + final String systemPropertiesConnectionResource = (String) System.getProperties().get(CONNECTION_PROPERTY_RESOURCE); + if (systemPropertiesConnectionResource != null) { + this.setConnectionResource(systemPropertiesConnectionResource); + } } /** Modified: java/trunk/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java ============================================================================= --- java/trunk/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java (original) +++ java/trunk/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java Fri Sep 4 12:59:35 2015 @@ -7,11 +7,9 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Calendar; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; -import java.util.Locale; import java.util.TimeZone; import org.apache.commons.csv.CSVFormat; Modified: java/trunk/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java ============================================================================= --- java/trunk/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java (original) +++ java/trunk/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java Fri Sep 4 12:59:35 2015 @@ -220,7 +220,7 @@ final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance(); DatabaseConditionsManager.getLogger().setLevel(Level.ALL); - manager.setTag("pass0"); + manager.addTag("pass0"); manager.setXmlConfig("/org/hps/conditions/config/conditions_database_engrun.xml"); final FileCache cache = new FileCache(); Copied: java/trunk/conditions/src/test/java/org/hps/conditions/api/ConditionsTagTest.java (from r3393, java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/api/ConditionsTagTest.java) ============================================================================= --- java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/api/ConditionsTagTest.java (original) +++ java/trunk/conditions/src/test/java/org/hps/conditions/api/ConditionsTagTest.java Fri Sep 4 12:59:35 2015 @@ -73,14 +73,15 @@ for (int run : RUNS) { MANAGER.setDetector("HPS-conditions-test", run); ConditionsRecordCollection conditionsRecordCollection = MANAGER.getConditionsRecords(); - System.out.println("run " + run + " has " + conditionsRecordCollection.size()); + System.out.println("run " + run + " has " + conditionsRecordCollection.size() + " conditions records"); System.out.println(conditionsRecordCollection); for (int i = 0; i < CONDITIONS.length; i++) { try { BaseConditionsObjectCollection<?> conditionsObjectCollection = BaseConditionsObjectCollection.class.cast( MANAGER.getCachedConditions(TYPES[i], CONDITIONS[i]).getCachedData()); - System.out.println("got collection " + conditionsObjectCollection.getTableMetaData().getTableName() + System.out.println("got collection " + conditionsObjectCollection.getTableMetaData().getTableName() + ":" + + conditionsObjectCollection.getCollectionId() + " with type " + conditionsObjectCollection.getTableMetaData().getCollectionClass().getName() + " and " + conditionsObjectCollection.size() + " objects"); } catch (Exception e) { Modified: java/trunk/evio/src/main/java/org/hps/evio/EvioToLcio.java ============================================================================= --- java/trunk/evio/src/main/java/org/hps/evio/EvioToLcio.java (original) +++ java/trunk/evio/src/main/java/org/hps/evio/EvioToLcio.java Fri Sep 4 12:59:35 2015 @@ -404,10 +404,13 @@ LOGGER.config("User set run number to " + runNumber + " with command option."); } - // Set the conditions system tag. + // Add conditions system tag filters. if (cl.hasOption("t")) { - final String tag = cl.getOptionValue("t"); - DatabaseConditionsManager.getInstance().setTag(tag); + final String[] tags = cl.getOptionValues("t"); + for (String tag : tags) { + LOGGER.config("adding conditions tag " + tag); + DatabaseConditionsManager.getInstance().addTag(tag); + } } // Is there a run number from the command line options?