/* * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute * Copyright [2016-2017] EMBL-European Bioinformatics Institute * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.ensembl.healthcheck; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import org.ensembl.healthcheck.util.DBUtils; /** * Class that stores information about which databases are available. */ public class DatabaseRegistry implements Iterable<DatabaseRegistryEntry> { // Entries is explicitly specified as an ArrayList rather than the list // because the order is important private ArrayList<DatabaseRegistryEntry> entries = new ArrayList<DatabaseRegistryEntry>(); // these global settings override guessing if they are specified private Species globalSpecies = null; private DatabaseType globalType = null; /** The logger to use */ private static Logger logger = Logger.getLogger("HealthCheckLogger"); // ----------------------------------------------------------------- /** * Create a new DatabaseRegistry. DatabaseRegistryEntry objects for the databases matching regexp are created and added to the * registry. * * @param regexps * The regular expressions matching the databases to use. If null, match everything. * @param isSecondary * If true, this is a secondary database registry. */ public DatabaseRegistry(List<String> regexps, DatabaseType globalType, Species globalSpecies, boolean isSecondary) { if (!isSecondary) { this.globalType = globalType; this.globalSpecies = globalSpecies; } List<DatabaseServer> servers = isSecondary ? DBUtils.getSecondaryDatabaseServers() : DBUtils.getMainDatabaseServers(); for (DatabaseServer server : servers) { if (regexps == null || regexps.size() == 0) { String[] names = null; try { names = DBUtils.listDatabases(server.getServerConnection(), null); } catch(SQLException e) { logger.warning(e.getMessage()); } addEntriesToRegistry(server, names, isSecondary); } else { Iterator<String> it = regexps.iterator(); while (it.hasNext()) { String regexp = it.next(); String[] names = null; try { names = DBUtils.listDatabases(server.getServerConnection(), regexp); } catch(SQLException e) { logger.warning(e.getMessage()); } addEntriesToRegistry(server, names, isSecondary); } } } } // ------------------------------------------------------------------------- /** * Create a new DatabaseRegistry from an array of DatabaseRegistryEntries. * * @param dbres * The entries to use. */ public DatabaseRegistry(final DatabaseRegistryEntry[] dbres) { for (int i = 0; i < dbres.length; i++) { entries.add(dbres[i]); } } // ------------------------------------------------------------------------- /** * Create a new DatabaseRegistry from a list of DatabaseRegistryEntries. * * @param dbres * The entries to use. */ public DatabaseRegistry(List<DatabaseRegistryEntry> dbres) { Iterator<DatabaseRegistryEntry> it = dbres.iterator(); while (it.hasNext()) { entries.add(it.next()); } } // ----------------------------------------------------------------- private void addEntriesToRegistry(DatabaseServer server, final String[] names, boolean isSecondary) { if (names==null) { return; } for (String name : names) { DatabaseRegistryEntry dbre = new DatabaseRegistryEntry(server, name, globalSpecies, globalType); if (!this.contains(dbre)) { // logger.finest(dbre.getName() + " appears to be type " + dbre.getType() + " and species " + dbre.getSpecies()); dbre.setDatabaseRegistry(this); entries.add(dbre); logger.finest("Added DatabaseRegistryEntry for " + name + " to " + (isSecondary ? "secondary" : "main") + " DatabaseRegistry"); } else { logger.finest("Registry already contains an entry for " + dbre.getName() + ", skipping"); } } } // ----------------------------------------------------------------- /** * Add a new DatabaseRegistryEntry to this registry. * * @param dbre * The new DatabaseRegistryEntry. */ public final void add(final DatabaseRegistryEntry dbre) { entries.add(dbre); dbre.setDatabaseRegistry(this); } // ----------------------------------------------------------------- /** * Get all of the DatabaseRegistryEntries stored in this DatabaseRegistry. * * @return The DatabaseRegistryEntries stored in this DatabaseRegistry. */ public final DatabaseRegistryEntry[] getAll() { return (DatabaseRegistryEntry[]) entries.toArray(new DatabaseRegistryEntry[entries.size()]); } // ----------------------------------------------------------------- /** * Get a list of all of the DatabaseRegistryEntries stored in this DatabaseRegistry. * * @return The DatabaseRegistryEntries stored in this DatabaseRegistry. */ public final List<DatabaseRegistryEntry> getAllEntries() { return entries; } // ----------------------------------------------------------------- /** * Get all of the DatabaseRegistryEntries for a particular species * * @param species * The species to look for. * @return The DatabaseRegistryEntries for species.. */ public final DatabaseRegistryEntry[] getAll(final Species species) { List<DatabaseRegistryEntry> result = new ArrayList<DatabaseRegistryEntry>(); Iterator<DatabaseRegistryEntry> it = entries.iterator(); while (it.hasNext()) { DatabaseRegistryEntry dbre = it.next(); if (dbre.getSpecies().equals(species)) { result.add(dbre); } } return (DatabaseRegistryEntry[]) result.toArray(new DatabaseRegistryEntry[result.size()]); } // ----------------------------------------------------------------- /** * Get all of the DatabaseRegistryEntries for a particular database type. * * @param type * The type to look for. * @return The DatabaseRegistryEntries for type. */ public final DatabaseRegistryEntry[] getAll(final DatabaseType type) { List<DatabaseRegistryEntry> result = new ArrayList<DatabaseRegistryEntry>(); Iterator<DatabaseRegistryEntry> it = entries.iterator(); while (it.hasNext()) { DatabaseRegistryEntry dbre = it.next(); if (dbre.getType().equals(type)) { result.add(dbre); } } return (DatabaseRegistryEntry[]) result.toArray(new DatabaseRegistryEntry[result.size()]); } // ----------------------------------------------------------------- /** * Get all of the DatabaseRegistryEntries for a particular database type and species. * * @param type * The type to look for. * @param species * The Species to look for. * @return The DatabaseRegistryEntries that match type and species.. */ public final DatabaseRegistryEntry[] getAll(final DatabaseType type, final Species species) { List<DatabaseRegistryEntry> result = new ArrayList<DatabaseRegistryEntry>(); Iterator<DatabaseRegistryEntry> it = entries.iterator(); while (it.hasNext()) { DatabaseRegistryEntry dbre = it.next(); if (dbre.getType().equals(type) && dbre.getSpecies().equals(species)) { result.add(dbre); } } return (DatabaseRegistryEntry[]) result.toArray(new DatabaseRegistryEntry[result.size()]); } // --------------------------------------------------------------------- /** * Get a single, named DatabaseRegistryEntry. * * @param name * The name to look for. * @return The matching DatabaseRegistryEntry, or null if none is found. */ public final DatabaseRegistryEntry getByExactName(String name) { Iterator<DatabaseRegistryEntry> it = entries.iterator(); while (it.hasNext()) { DatabaseRegistryEntry dbre = it.next(); if (dbre.getName().equals(name)) { return dbre; } } logger.warning("Can't find database matching name " + name); return null; } // ------------------------------------------------------------------------- /** * Get a list of the types of databases in the registry. * * @return A Set containing each DatabaseType found in the registry, each type only once. */ public final Set<DatabaseType> getUniqueTypes() { // using a Set here gets uniqueness for free Set<DatabaseType> types = new HashSet<DatabaseType>(); for (DatabaseRegistryEntry dbre : entries) { types.add(dbre.getType()); } return types; } // ------------------------------------------------------------------------- /** * Get a list of the types of databases in the registry. * * @return An array containing each DatabaseType found in the registry. */ public final DatabaseType[] getTypes() { Set <DatabaseType> types = getUniqueTypes(); return (DatabaseType[]) types.toArray(new DatabaseType[types.size()]); } // ------------------------------------------------------------------------- /** * Get a list of the species in the registry. * * @return An array containing each Species found in the registry. */ public final Set<Species> getUniqueSpecies() { // using a Set here gets uniqueness for free Set<Species> species = new HashSet<Species>(); for (DatabaseRegistryEntry dbre : entries) { species.add(dbre.getSpecies()); } return species; } // ------------------------------------------------------------------------- /** * Get a list of the species in the registry. * * @return An array containing each Species found in the registry. */ public final Species[] getSpecies() { Set<Species> species = getUniqueSpecies(); return (Species[]) species.toArray(new Species[species.size()]); } //------------------------------------------------------------------------- /** * Get a Map containing the list of types for each species. * * @return A map (key:Species, value:Set of DatabaseTypes). */ public final Map<Species, Set<DatabaseType>> getSpeciesTypeMap() { Map<Species, Set<DatabaseType>> result = new HashMap<Species, Set<DatabaseType>>(); for (DatabaseRegistryEntry dbre : entries) { Species species = dbre.getSpecies(); // add species with empty Set of types if required if (!result.containsKey(species)) { result.put(species, new HashSet<DatabaseType>()); } // add type to set of types Set<DatabaseType> types = result.get(species); types.add(dbre.getType()); } return result; } // ----------------------------------------------------------------- /** * @return The number of DatabaseRegistryEntries in this registry. */ public final int getEntryCount() { return entries.size(); } // ----------------------------------------------------------------- /** * @return true if this registry is empty. */ public final boolean isEmpty() { return entries.size() == 0; } // ----------------------------------------------------------------- /** * @return True if this registry contains a particular DatabaseRegistryEntry (note equals() method in DatabaseRegistryEntry * determines this behaviour). */ public boolean contains(DatabaseRegistryEntry dbre) { for (DatabaseRegistryEntry entry : entries) { if (entry.equals(dbre)) { return true; } } return false; } // ----------------------------------------------------------------- /** * @return List of entries from this registry that match a regexp. Note that this will be a subset of the entries that the * registry was created from (based on another regexp!) */ public List<DatabaseRegistryEntry> getMatching(String regexp) { List<DatabaseRegistryEntry> result = new ArrayList<DatabaseRegistryEntry>(); for (DatabaseRegistryEntry entry : entries) { if (entry.getName().matches(regexp)) { result.add(entry); } } return result; } /** * Implement Iterable interface */ public Iterator<DatabaseRegistryEntry> iterator() { return entries.iterator(); } // ----------------------------------------------------------------- } // DatabaseRegistry