001    /**
002     * Copyright (C) 2010 The Roslin Institute <contact andy.law@roslin.ed.ac.uk>
003     *
004     * This file is part of the Ensembl Java API demonstration project developed by the
005     * Bioinformatics Group at The Roslin Institute, The Royal (Dick) School of
006     * Veterinary Studies, University of Edinburgh.
007     *
008     * This is free software: you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (dbVersion 3) as published by
010     * the Free Software Foundation.
011     *
012     * This software is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015     * GNU General Public License for more details.
016     *
017     * You should have received a copy of the GNU General Public License
018     * in this software distribution. If not, see <http://www.gnu.org/licenses/gpl-3.0.html/>.
019     */
020    package uk.ac.roslin.ensembl.dao.database;
021    
022    
023    import java.io.InputStreamReader;
024    import java.io.Reader;
025    import java.util.ArrayList;
026    import java.util.Arrays;
027    import java.util.Collection;
028    import java.util.HashMap;
029    import java.util.Iterator;
030    import java.util.List;
031    import java.util.logging.Level;
032    import uk.ac.roslin.ensembl.config.DBConnection.DataSource;
033    import uk.ac.roslin.ensembl.exception.DAOException;
034    import java.util.Properties;
035    import java.util.TreeMap;
036    import java.util.TreeSet;
037    import org.apache.ibatis.session.SqlSession;
038    import org.apache.ibatis.session.SqlSessionFactory;
039    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
040    import org.apache.log4j.Logger;
041    import uk.ac.roslin.ensembl.config.DBConnection;
042    import uk.ac.roslin.ensembl.model.database.CollectionDatabase;
043    import uk.ac.roslin.ensembl.model.database.Database;
044    import uk.ac.roslin.ensembl.model.database.DatabaseType;
045    import uk.ac.roslin.ensembl.exception.ConfigurationException;
046    import uk.ac.roslin.ensembl.model.core.Species;
047    import uk.ac.roslin.ensembl.model.database.CollectionCoreDatabase;
048    import uk.ac.roslin.ensembl.model.database.Registry;
049    import uk.ac.roslin.ensembl.config.EnsemblDBType;
050    import uk.ac.roslin.ensembl.config.EnsemblComparaDivision;
051    import uk.ac.roslin.ensembl.config.FeatureType;
052    import uk.ac.roslin.ensembl.config.RegistryConfiguration;
053    import uk.ac.roslin.ensembl.config.SchemaVersion;
054    import uk.ac.roslin.ensembl.mapper.DatabaseMapper;
055    import uk.ac.roslin.ensembl.model.core.CollectionSpecies;
056    import uk.ac.roslin.ensembl.model.database.ComparisonDatabase;
057    import uk.ac.roslin.ensembl.model.database.SingleSpeciesCoreDatabase;
058    import uk.ac.roslin.ensembl.model.database.SingleSpeciesDatabase;
059    
060    public class DBRegistry
061            implements Registry {
062    
063        final static Logger LOGGER = Logger.getLogger(DBRegistry.class);
064    
065        protected SqlSessionFactory sqlMapper;
066    
067        protected Properties configProperties = new Properties();
068        protected SchemaVersion schemaVersion = null;
069        protected DBConnection dbConnection = null;
070        private String mostRecentEnsemblVersion;
071        private String mostRecentGenomesVersion;
072    
073        //incase the datasource does not include the 'current' dbVersion
074        private int highestEnsemblVersion = 0;
075        private int highestVersion = 0;
076    
077        protected TreeSet<Integer> knownSchemaVersions = new TreeSet<Integer>();
078    
079        //the mybatis configProperties for database connection
080        private String baseMybatis;
081    
082        //to read the mybatis regConfig
083        protected Reader reader;
084    
085        protected TreeMap<String, DBSpecies> speciesHash = new TreeMap<String, DBSpecies>();
086        protected TreeMap<String, DBCollectionSpecies> collectionspeciesHash = new TreeMap<String, DBCollectionSpecies>();
087        protected List<DBCollection> collections = new ArrayList<DBCollection>();
088    
089        //we need a separate one of these for each collection (dbVersion) as they will grow
090        protected TreeMap<String, TreeMap<String, DBCollection>> collectionNameDBVersionHash = new TreeMap<String, TreeMap<String, DBCollection>>();
091        protected TreeMap<String, String> ensemblNameForAliasHash = new TreeMap<String, String>();
092    
093        //the databases
094        protected TreeSet<DBDatabase> allDatabases = new TreeSet<DBDatabase>();
095        protected TreeSet<DBSingleSpeciesDatabase> singleSpeciesDatabases = new TreeSet<DBSingleSpeciesDatabase>();
096        protected TreeSet<DBComparisonDatabase> comparisonDatabases = new TreeSet<DBComparisonDatabase>();
097        
098        //HashMap of comparison databases indexed on 'group' , then on 'dbVersion' (not schema dbVersion)
099        protected HashMap<EnsemblComparaDivision, HashMap<String,DBComparisonDatabase>> comparaDBByDivision =
100                new HashMap<EnsemblComparaDivision, HashMap<String,DBComparisonDatabase>>();
101    
102        protected TreeSet<DBCollectionDatabase> collectionDatabases = new TreeSet<DBCollectionDatabase>();
103        protected String newline = (System.getProperty("line.separator") != null) ? System.getProperty("line.separator") : "\r\n";
104        protected StringBuffer tooNewDB = new StringBuffer();
105        protected StringBuffer unknownDB = new StringBuffer();
106    
107        protected RegistryConfiguration regConfig = null;
108        DataSource datasourceType;
109        protected boolean alreadyInitialized = false;
110    
111        /**
112         * Parameterless public constructor for DBRegistry object
113         */
114        public DBRegistry()  {
115            
116        }
117    
118        /**
119         * Public Constructor for default value DBRegistry object, using values in
120         * ensembl-config artifact. This intializes the database connection so will fail
121         * if connection parameters are wrong etc.
122         * @param type DBConnection.DataSource
123         * @throws ConfigurationException
124         * @throws DAOException
125         */
126        public DBRegistry(DataSource type) throws ConfigurationException, DAOException {
127            this.setConfiguration(type);
128            this.initialize();
129        }
130        /**
131         * Public Constructor for default value DBRegistry object, using values in
132         * ensembl-config artifact. Boolean parameter allows a REgistry to be configured
133         * without calling initialization (useful for tests);
134         * @param type DBConnection.DataSource
135         * @param initialize boolean
136         * @throws ConfigurationException
137         * @throws DAOException
138         */
139        public DBRegistry(RegistryConfiguration conf, boolean initialize) throws ConfigurationException, DAOException {
140            this.setConfiguration(conf);
141            if (initialize) {
142                 this.initialize();
143            }
144    
145        }
146    
147        public void setConfiguration(RegistryConfiguration conf) throws ConfigurationException, DAOException {
148            this.regConfig = conf;
149            this.datasourceType = regConfig.getType();
150            this.dbConnection = regConfig.getDb();
151            this.configProperties.putAll(dbConnection.getConfigurationProperties());
152            this.schemaVersion = regConfig.getSchema();
153            this.configProperties.putAll(schemaVersion.getConfigurationProperties());
154            this.mostRecentEnsemblVersion = this.schemaVersion.getCurrentEnsemblVersion();
155            this.mostRecentGenomesVersion = this.schemaVersion.getCurrentGenomesVersion();
156            String[] versions = schemaVersion.getRegisteredSchemas();
157    
158            for (int i = 0; i < versions.length; i++) {
159                this.knownSchemaVersions.add(Integer.parseInt(versions[i]));
160            }
161    
162            LOGGER.info("This application is configured to use schema version " + mostRecentEnsemblVersion
163                    + " of Ensembl, and knows about the schema versions: " + Arrays.toString(versions));
164    
165    
166            // mybatis configProperties for databaseDAO
167            this.baseMybatis = this.schemaVersion.getBaseMybatis();
168            try {
169                reader = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(baseMybatis));
170                //this doesn't work once you bundle up
171                //reader = Resources.getResourceAsReader(baseMybatis);
172            } catch (Exception ex) {
173                throw new ConfigurationException("Fail to read Mybatis Configuration for initial Database connection", ex);
174            }
175            try {
176                sqlMapper = new SqlSessionFactoryBuilder().build(reader, "current", configProperties);
177                if (sqlMapper==null) {
178                    throw new Exception("SqlSessionFactory is null");
179                }
180            } catch (Exception e) {
181                throw new ConfigurationException("The DBRegistry is unable to make a SqlSessionFactory", e);
182            }
183        }
184    
185        public void setConfiguration(DataSource type) throws ConfigurationException, DAOException {
186            this.setConfiguration(new RegistryConfiguration(type));
187        }
188    
189    //    /**
190    //     * Public Constructor for a DBRegistry, to be configures and initialized using
191    //     * settings in the RegistryConfiguration parameter.
192    //     * @param conf RegistryConfiguration
193    //     * @throws ConfigurationException
194    //     * @throws DAOException
195    //     */
196    //    public DBRegistry(RegistryConfiguration conf) throws ConfigurationException, DAOException {
197    //        this.setConfiguration(conf);
198    //    }
199    
200        /**
201         * private initialisation method for the registry which connects to ensembl 
202         * via a DBDatasourceDAO and retreives details on all the current tables and 
203         * creates database objects of the appropriate type for each.
204         * Also retrieves dbSpeciesName aliases for all the current release dbSpeciesName.
205         * And finds out what dbSpeciesName are present in multispecies databases.
206         *
207         * @throws DAOException, ConfigurationException
208         */
209        public void initialize() throws DAOException, ConfigurationException {
210    
211            if (this.alreadyInitialized) {
212                throw new ConfigurationException("Tried to re-initialize a DBRegistry");
213            } 
214    
215            //populates the names of all the databases available, excluding marts, test, mysql and information_schema
216            LOGGER.info("Registry is loading and sorting all databases available from this source ("
217                    + this.dbConnection.getConfigurationProperties().getProperty("url") + "):");
218    
219            for (String s : this.getDatabases()) {
220    
221                if (dbConnection.isDBNameValid(s)) {
222                    try {
223                        DBDatabase db = this.makeDatabase(s.trim());
224    
225                        if (db.intSchemaVersion > Integer.parseInt(this.mostRecentEnsemblVersion)) {
226                            LOGGER.warn("IGNORING Database " + s + " with higher schema number ("
227                                    + db.getSchemaVersion() + ") than application configuration (" + this.mostRecentEnsemblVersion + ").");
228                            tooNewDB.append(s + newline);
229                        } else if (!this.knownSchemaVersions.contains(Integer.parseInt(db.getSchemaVersion()))) {
230                            LOGGER.warn("IGNORING Database " + s + " with schema number ("
231                                    + db.getSchemaVersion() + ") not found in the application configuration.");
232                            unknownDB.append(s + newline);
233                        } else {
234                            this.registerDatabase(db);
235                        }
236    
237                    } catch (Exception e) {
238                        LOGGER.warn("Unspecified error thrown trying to make a Database object for '" + s + "'", e);
239                    }
240                }
241            }
242    
243    
244    
245            //get all the core databases for the current release
246            //so that we can create Species database objects for each of these
247            //filling in the aliases and some other properties
248            //we then put these in a hash against genus_species
249    
250            //BUG: if the datasource doesnt have any current releases
251            //e.g. if configured to load ensembldb_archives
252            //we wont make any species -
253            //need a work around if this is the case - to use the highest release dbVersion found
254    
255    
256            TreeSet<DBSingleSpeciesDatabase> badDatabases = new TreeSet<DBSingleSpeciesDatabase>();
257    
258            for (DBSingleSpeciesDatabase d : this.singleSpeciesDatabases) {
259    
260                if (d.type == EnsemblDBType.core && d.getIntDBVersion() == this.highestVersion) {
261                    
262                    DBSpecies spData = null;
263    
264                    //this can fail if there is something wrong with the database!
265                    try {
266                        spData = this.getSpeciesProperties((DBSingleSpeciesCoreDatabase) d);
267                    } catch (DAOException dAOE) {
268                        LOGGER.info("Failed to create a species for current core database: "+d.getdBName()
269                                +": Removed this database!", dAOE );
270                    }
271                    if (spData != null) {
272                        d.setSpecies(spData);
273                        speciesHash.put(spData.getDatabaseStyleName(), spData);
274                    } else {
275                        //store this as a bad (current) database
276                        badDatabases.add(d);
277                    }
278                }
279    
280            }
281    
282            //remove any databases that i cant make a species for!
283            this.singleSpeciesDatabases.removeAll(badDatabases);
284            this.allDatabases.removeAll(badDatabases);
285    
286    
287    
288            // the collections will add members with time - so each collectionDB needs
289            //its own Collection
290    
291            //get all the collection_core databases 
292            //so that we can create Collection database objects for each of these
293            //and populate it with CollectionSpecies objects for this collection
294    
295            // however we will reuse existing CollectionSpecies objects
296            // and only add new ones to the registry
297    
298    
299           TreeSet<DBCollectionDatabase> badCollectionDatabases = new TreeSet<DBCollectionDatabase>();
300    
301            for (DBCollectionDatabase d : this.collectionDatabases) {
302                if (d.type == EnsemblDBType.collection_core) {
303    
304                    // make a registrycollection for each collection core database
305                    //as these may differ over time
306                    DBCollection thisCollection = null;
307                    try {
308                        thisCollection = this.getCollectionSpeciesProperties((CollectionCoreDatabase) d);
309                    } catch (DAOException ex) {
310                        LOGGER.info("Failed to create a collectionfor current core database: "+d.getdBName()
311                                +": Removed this database!", ex);
312                    }
313    
314                    if (thisCollection!=null) {
315    
316                        this.collections.add(thisCollection);
317                        //d.setCollection(r);
318    
319                        if (this.collectionNameDBVersionHash.containsKey(thisCollection.getCollectionName())) {
320                            this.collectionNameDBVersionHash.get(thisCollection.getCollectionName()).put(d.getDBVersion(), thisCollection);
321                        } else {
322                            TreeMap<String, DBCollection> map = new TreeMap<String, DBCollection>();
323                            map.put(d.getDBVersion(), thisCollection);
324                            this.collectionNameDBVersionHash.put(thisCollection.getCollectionName(), map);
325                        }
326                    } else {
327                        badCollectionDatabases.add(d);
328                    }
329                }
330            }
331    
332            this.collectionDatabases.removeAll(badCollectionDatabases);
333            this.allDatabases.removeAll(badCollectionDatabases);
334    
335            // we need to set the collections on the other types of collection databases
336            for (DBCollectionDatabase d : this.collectionDatabases) {
337                if (d.type != EnsemblDBType.collection_core) {
338    
339                    String dbVersion = d.getDBVersion();
340                    String cName = d.getCollectionName();
341    
342                    if (this.collectionNameDBVersionHash.containsKey(cName)
343                            && this.collectionNameDBVersionHash.get(cName).containsKey(dbVersion)) {
344                        d.setCollection(this.collectionNameDBVersionHash.get(cName).get(dbVersion));
345                    }
346    
347                }
348            }
349    
350    
351    
352            //we now populate the look up hash for aliases
353            //and at the same time add all the relevant databases to each DBSpecies
354            //and vice versa
355    
356            for (DBSpecies sp : speciesHash.values()) {
357    
358    
359                for (String s : sp.getAliases()) {
360                    this.ensemblNameForAliasHash.put(s, sp.getDatabaseStyleName());
361                }
362    
363                for (DBSingleSpeciesDatabase d : this.singleSpeciesDatabases) {
364                    if (d.getDbSpeciesName().equalsIgnoreCase(sp.getDatabaseStyleName())) {
365                        sp.addDatabase(d);
366                        if (d.getSpecies() == null) {
367                            d.setSpecies(sp);
368                        }
369                    }
370                }
371    
372            }
373    
374            for (DBCollectionSpecies sp : collectionspeciesHash.values()) {
375                for (String s : sp.getAliases()) {
376                    this.ensemblNameForAliasHash.put(s, sp.getDatabaseStyleName());
377                }
378    
379    
380                for (DBCollectionDatabase d : this.collectionDatabases) {
381                    try {
382    
383                        if (EnsemblDBType.getCollectionDatabaseTypes().contains(d.getType())
384                                && d.getCollection().getSpecies().contains(sp)) {
385                            sp.addDatabase(d);
386                        }
387                    } catch (Exception e) {
388                    }
389    
390                }
391    
392    
393    
394            }
395    
396            //add all the relevant databases to each DBCollection
397    
398    
399            Iterator<String> it = this.collectionNameDBVersionHash.keySet().iterator();
400    
401            while (it.hasNext()) {
402    
403                String name = it.next();
404    
405                Iterator<String> it2 = this.collectionNameDBVersionHash.get(name).keySet().iterator();
406    
407                while (it2.hasNext()) {
408                    String dbversion = it2.next();
409    
410                    DBCollection collection = this.collectionNameDBVersionHash.get(name).get(dbversion);
411    
412                    TreeSet<CollectionDatabase> temp = new TreeSet<CollectionDatabase>();
413                    for (DBCollectionDatabase d : this.collectionDatabases) {
414                        if (d.getCollectionName().equals(name) && d.getDBVersion().equalsIgnoreCase(dbversion.toString())) {
415                            temp.add((CollectionDatabase) d);
416                        }
417                    }
418                    collection.addDatabases(temp);
419    
420                }
421            }
422            this.alreadyInitialized = true;
423        }
424    
425        // Database look up methods
426        @Override
427        public DBDatabase getDatabase(String species_name_or_alias) {
428            return getDatabase(species_name_or_alias, null, null);
429        }
430    
431        @Override
432        public DBDatabase getDatabase(String species_name_or_alias, String db_version) {
433            return getDatabase(species_name_or_alias, null, db_version);
434        }
435    
436        @Override
437        public DBDatabase getDatabase(String speciesNameOrAlias_collectionName_comparaDivision, DatabaseType database_type, String db_version) {
438    
439            String name = speciesNameOrAlias_collectionName_comparaDivision;
440    
441            DBDatabase out = null;
442    
443            //default to CORE type if not provided
444            EnsemblDBType type = (database_type != null
445                    && database_type.toString() != null
446                    && !database_type.toString().equals(""))
447                    ? (EnsemblDBType) database_type
448                    : EnsemblDBType.core;
449    
450           if (name==null || name.isEmpty()) {
451                if (EnsemblDBType.getSpeciesComparisonDatabaseTypes().contains(type)) {
452                    name = "multi";
453                } else {
454                    //deff out if no name
455                    return out;
456                }
457            }
458    
459            //default to current dbVersion if not provided
460            String version = (db_version != null
461                    && !db_version.isEmpty()
462                    && !db_version.equals("current"))
463                    ? db_version
464                    : this.getMostRecentDBVersion();
465    
466            String speciesOrGroup = "";
467    
468            if (EnsemblDBType.getSpeciesComparisonDatabaseTypes().contains(type)) {
469                //no look up possible
470                speciesOrGroup = name;
471            } else if (EnsemblDBType.getSingleSpeciesDatabaseTypes().contains(type)) {
472                //do a look up for aliases
473                speciesOrGroup = this.getEnsemblNameForAlias(name);
474                if (speciesOrGroup == null) {
475                    //deff out
476                    return out;
477                }
478            } else if (EnsemblDBType.getCollectionDatabaseTypes().contains(type)) {
479                //no look up possible
480                speciesOrGroup = name;
481            }
482    
483    
484            if (EnsemblDBType.getSingleSpeciesDatabaseTypes().contains(type)) {
485                for (DBSingleSpeciesDatabase d : this.singleSpeciesDatabases) {
486                    if (d.getDbSpeciesName().equals(speciesOrGroup)
487                            && d.getDBVersion().equals(version)
488                            && d.getType() == type) {
489                        return d;
490                    }
491                }
492            } else if (EnsemblDBType.getSpeciesComparisonDatabaseTypes().contains(type)) {
493    
494                EnsemblComparaDivision gp = EnsemblComparaDivision.getEnsemblComparaDivision(speciesOrGroup);
495                for (DBComparisonDatabase d : this.comparisonDatabases) {
496                    if (d.getComparisonDivision().equals(gp)
497                            && d.getDBVersion().equals(version)
498                            && d.getType() == type) {
499                        return d;
500                    }
501                }
502            }        //this is only working on Groups not ind species
503            else if (EnsemblDBType.getCollectionDatabaseTypes().contains(type)) {
504                for (DBCollectionDatabase d : this.collectionDatabases) {
505                    if (d.getCollectionName().equals(speciesOrGroup)
506                            && d.getDBVersion().equals(version)
507                            && d.getType() == type) {
508                        return d;
509                    }
510                }
511            }
512    
513    
514            return out;
515        }
516    
517        @Override
518        public ComparisonDatabase getComparaDatabase(EnsemblComparaDivision comparaDivision, String db_version) {
519    
520            if (this.comparaDBByDivision.get(comparaDivision) != null) {
521                return this.comparaDBByDivision.get(comparaDivision).get(db_version);
522            } else {
523                return null;
524            }
525        }
526    
527        @Override
528        public DBDatabase getDatabaseForFullName(String fullname) {
529    
530            DBDatabase out = null;
531    
532            if (fullname==null || fullname.isEmpty()) {
533                return out;
534            }
535    
536            for (DBDatabase d : this.allDatabases) {
537                if (d.getdBName().equals(fullname)) {
538                    out = d;
539                    break;
540                }
541            }
542            return out;
543        }
544    
545        @Override
546        public TreeSet<DBDatabase> getDatabasesByType(DatabaseType type) {
547            TreeSet<DBDatabase> out = new TreeSet<DBDatabase>();
548    
549            for (DBDatabase d : this.allDatabases) {
550                if (d.getType() == type) {
551                    out.add(d);
552                }
553            }
554            return out;
555        }
556    
557        @Override
558        public String findMybatisSchemaForSchemaVersion(DatabaseType type, String schema_version) {
559    
560            String out = null;
561    
562            try {
563                out = schemaVersion.getMybatisSchemaPath(type.toString(), schema_version);
564            } catch (Exception e) {
565            }
566    
567            //
568    
569            if (out == null) {
570                try {
571                    out = schemaVersion.getMybatisSchemaPath(type.toString(), schemaVersion.getCurrentEnsemblVersion());
572                } catch (Exception e) {
573                }
574            }
575    
576            return out;
577        }
578    
579        /**
580         * Looks up the ensembl_genus_species_name for the given alias from the
581         * ensemblNameForAliasHash hash of aliases in this Registry.
582         * @param alias String
583         * @return String the ensembl_genus_species_name
584         */
585        @Override
586        public String getEnsemblNameForAlias(String alias) {
587            if (alias==null) {
588                return null;
589            }
590            if (ensemblNameForAliasHash.containsValue(alias)) {
591                return alias;
592            }
593            return ensemblNameForAliasHash.get(alias);
594        }
595    
596        /**
597         * Method for an adhoc alias to be added by the user in this session. Adds
598         * the alias to the aliases TreeSet of the cognate DBSpecies and to
599         * the ensemblNameForAliasHash hash of aliases in this Registry
600         * @param ensembl_genus_species_name Ensmebl databse dbVersion of the name, e.g. 'homo_sapiens'
601         * @param alias any string the user wants to use an alias for this
602         * @return boolean true if successful
603         * @throws Exception if update fails, with meaning full message
604         */
605        @Override
606        public boolean addSessionAlias(String ensembl_genus_species_name, String alias) throws Exception {
607    
608            if(ensembl_genus_species_name==null || alias==null || ensembl_genus_species_name.isEmpty() || alias.isEmpty() ) {
609                throw new Exception("Failed to add alias: " + alias + " for species: " + ensembl_genus_species_name);
610            }
611    
612            Species spData = null;
613    
614    
615            try {
616                spData = this.speciesHash.get(ensembl_genus_species_name);
617                if (spData == null) {
618                    spData = this.collectionspeciesHash.get(ensembl_genus_species_name);
619                    if (spData == null) {
620                        throw new Exception("No species in ensembl registry called: " + ensembl_genus_species_name);
621                    }
622                }
623                spData.getAliases().add(alias);
624                this.ensemblNameForAliasHash.put(alias, ensembl_genus_species_name);
625                return true;
626            } catch (Exception e) {
627                throw new Exception("Failed to add alias: " + alias + " for species: " + ensembl_genus_species_name);
628            }
629    
630        }
631    
632        @Override
633        public Properties getConfigProperties() {
634            return configProperties;
635        }
636    
637        @Override
638        public StringBuffer printRegistryReport() {
639            StringBuffer out = new StringBuffer();
640    
641            if (this.regConfig==null) {
642                out.append("This Registry object has not been configured"+newline);
643                return out;
644            }
645    
646            out.append("Registry for: " + this.dbConnection.getConfigurationProperties().getProperty("url")+newline);
647    
648            out.append(dbConnection.report()+newline);
649    
650            out.append(" Current Ensembl Release: " + this.mostRecentEnsemblVersion+newline);
651            out.append(" Current EnsemblGenomes Release: " + this.mostRecentGenomesVersion+newline);
652            out.append(" Current DB Version: " + this.getMostRecentDBVersion()+newline);
653    
654            if (!this.alreadyInitialized) {
655                out.append("This configured Registry has not yet been initialized"+newline);
656                return out;
657            }
658    
659            if (tooNewDB.toString() != null && !tooNewDB.toString().isEmpty()) {
660                out.append("Some database releases were too recent for the current JEnsembl configuration:"
661                        + newline + tooNewDB.toString());
662            }
663            if (unknownDB.toString() != null && !unknownDB.toString().isEmpty()) {
664                out.append("Some database releases were not known in the current JEnsembl configuration:"
665                        + newline + unknownDB.toString());
666            }
667    
668    
669            out.append(newline+"___________________________"+newline);
670            out.append("Species in Ensembl (with aliases):"+newline);
671            out.append("\tSingle Species"+newline+"______________"+newline);
672    
673            for (DBSpecies s : this.speciesHash.values()) {
674                out.append(s.getSpeciesBinomial() + " [" + s.getDatabaseStyleName() + "] (");
675                for (String st : s.getAliases()) {
676                    out.append(st + ", ");
677                }
678                try {
679                    out.append(")"+newline+"\tCurrent Core Database: " + s.getCurrentCoreDatabase().getdBName()  +newline);
680    
681                    for (FeatureType key : ((DBSingleSpeciesCoreDatabase) s.getCurrentCoreDatabase()).getBuildLevels().keySet()) {
682                        out.append(key.toString() + " : " + ((DBSingleSpeciesCoreDatabase) s.getCurrentCoreDatabase()).getBuildLevels().get(key) + "\n");
683                    }
684    
685                } catch (Exception e) {
686                    out.append(")"+newline+"\tNO Current Core Database"+newline);
687                }
688            }
689    
690    
691            out.append(newline+"_____________"+newline+"CollectionDatabase Species"+newline+"______________"+newline);
692    
693            if (this.collectionspeciesHash.values().isEmpty()) {
694                out.append(newline+"NONE"+newline);
695            }
696    
697            for (DBCollectionSpecies s : this.collectionspeciesHash.values()) {
698                out.append(s.getSpeciesBinomial() + " [" + s.getDatabaseStyleName() + "] (");
699                for (String st : s.getAliases()) {
700                    out.append(st + ", ");
701                }
702                try {
703                    out.append(")"+newline+"\tCurrent Core Database: " + s.getCurrentCoreDatabase().getdBName() +newline);
704                } catch (Exception e) {
705                    out.append(")"+newline+"\tNO Current Core Database"+newline);
706                }
707            }
708    
709    
710    
711            out.append("\n____________________\n\n\nMulti Species Databases: ");
712            out.append("\n________________________\n\n");
713            for (EnsemblDBType t : EnsemblDBType.getSpeciesComparisonDatabaseTypes()) {
714                out.append(t.toString() + ":\n");
715                for (Database d : this.getDatabasesByType(t)) {
716                    out.append("\t" + d.getdBName() + "\n");
717                }
718            }
719    
720    
721            out.append("\nSingleSpecies Database details: ");
722            out.append("\n________________________\n\n");
723    
724            for (DBSpecies sp : this.speciesHash.values()) {
725                String id = sp.getSpeciesBinomial();
726                out.append(id + "\n__________________\n");
727    
728    
729                out.append("\n\tCurrent Versions:\n");
730                for (Database d : sp.getDatabasesByVersion(this.getMostRecentDBVersion())) {
731                    out.append("\t\t" + d.getdBName() + "\n");
732                }
733                out.append("\tBy Type:\n");
734                for (EnsemblDBType t : EnsemblDBType.getSingleSpeciesDatabaseTypes()) {
735    
736                    out.append("\t" + t.toString() + "\n");
737                    if (sp.getDatabasesByType(t).isEmpty()) {
738                        out.append("\t\tNONE\n");
739                    } else {
740                        for (Database d : sp.getDatabasesByType(t)) {
741                            out.append("\t\t" + d.getdBName() + "\n");
742                        }
743                    }
744                }
745    
746            }
747            out.append("\nCollectionSpecies Database details: ");
748            out.append("\n________________________\n\n");
749    
750            if (this.collectionspeciesHash.values().isEmpty()) {
751                out.append("\nNONE\n");
752            }
753    
754            for (DBCollectionSpecies sp : this.collectionspeciesHash.values()) {
755                String id = sp.getSpeciesBinomial();
756                out.append(id + "\n__________________\n");
757    
758    
759                out.append("\n\tCurrent Versions:\n");
760                for (Database d : sp.getDatabasesByVersion(this.getMostRecentDBVersion())) {
761                    out.append("\t\t" + d.getdBName() + "\n");
762                }
763                out.append("\tBy Type:\n");
764                for (EnsemblDBType t : EnsemblDBType.getCollectionDatabaseTypes()) {
765    
766                    out.append("\t" + t.toString() + "\n");
767                    if (sp.getDatabasesByType(t).isEmpty()) {
768                        out.append("\t\tNONE\n");
769                    } else {
770                        for (Database d : sp.getDatabasesByType(t)) {
771                            out.append("\t\t" + d.getdBName() + "\n");
772                        }
773                    }
774                }
775            }
776    
777            out.append("\nCore Collection Databases: Species and build information");
778            out.append("\n________________________________________________________\n");
779    
780            if (this.collectionDatabases.isEmpty()) {
781                out.append("\nNONE\n");
782            }
783    
784            for (DBCollectionDatabase d : this.collectionDatabases) {
785                if (d.getType().equals(EnsemblDBType.collection_core)) {
786    
787                    out.append("\nCORECOLLECTION DB: " + d.dBName + "\n");
788    
789                    for (DBCollectionSpecies species : d.getCollection().getSpecies()) {
790    
791                        DBCollectionCoreDatabase db = (DBCollectionCoreDatabase) d;
792                        out.append("\tSPECIES: " + species.commonName + "\n");
793    
794    
795                        for (FeatureType key : db.getBuildLevels(species).keySet()) {
796                            out.append("\t\t" + key.toString() + " : " + db.getBuildLevels(species).get(key) + "\n");
797                        }
798    
799    
800                    }
801                }
802            }
803    
804    
805            return out;
806        }
807    
808        @Override
809        public DBSpecies getSpeciesByAlias(String alias_or_name) {
810            if (alias_or_name==null||alias_or_name.isEmpty()) {
811                return null;
812            }
813    
814            DBSpecies out = null;
815            out = (this.getEnsemblNameForAlias(alias_or_name) != null
816                    && this.speciesHash.get(this.getEnsemblNameForAlias(alias_or_name)) != null)
817                    ? this.speciesHash.get(this.getEnsemblNameForAlias(alias_or_name))
818                    : null;
819            if (out == null) {
820                out = (this.getEnsemblNameForAlias(alias_or_name) != null
821                        && this.collectionspeciesHash.get(this.getEnsemblNameForAlias(alias_or_name)) != null)
822                        ? this.collectionspeciesHash.get(this.getEnsemblNameForAlias(alias_or_name))
823                        : null;
824            }
825    
826            return out;
827        }
828    
829        @Override
830        public DBSpecies getSpeciesByEnsemblName(String ensemblName) {
831            if (ensemblName==null||ensemblName.isEmpty()) {
832                return null;
833            }
834    
835            DBSpecies out = null;
836            out = this.speciesHash.get(ensemblName);
837            if (out == null) {
838                out = this.collectionspeciesHash.get(ensemblName);
839            }
840    
841            return out;
842        }
843    
844        @Override
845        public String getMostRecentEnsemblVersion() {
846            return mostRecentEnsemblVersion;
847        }
848    
849        @Override
850        public DBCollection getCollection(String name, String dbVersion) {
851            DBCollection out = null;
852            if (name==null||name.isEmpty()||dbVersion==null||dbVersion.isEmpty()) {
853                return out;
854            }
855            if (this.collectionNameDBVersionHash.containsKey(name)) {
856                if (this.collectionNameDBVersionHash.get(name).containsKey(dbVersion)) {
857                    out = this.collectionNameDBVersionHash.get(name).get(dbVersion);
858                }
859            }
860            return out;
861        }
862    
863        private void registerDatabase(DBDatabase db) {
864            if (db instanceof DBCollectionDatabase) {
865                this.collectionDatabases.add((DBCollectionDatabase) db);
866                if (db.intSchemaVersion > this.highestEnsemblVersion) {
867                    this.highestEnsemblVersion = db.intSchemaVersion;
868                }
869                if (db.intDBVersion > this.highestVersion) {
870                    this.highestVersion = db.intDBVersion;
871                }
872            } else if (db instanceof DBSingleSpeciesDatabase) {
873                this.singleSpeciesDatabases.add((DBSingleSpeciesDatabase) db);
874                if (db.intSchemaVersion > this.highestEnsemblVersion) {
875                    this.highestEnsemblVersion = db.intSchemaVersion;
876                }
877                if (db.intDBVersion > this.highestVersion) {
878                    this.highestVersion = db.intDBVersion;
879                }
880            } else if (db instanceof DBComparisonDatabase) {
881                this.comparisonDatabases.add((DBComparisonDatabase) db);
882    
883                if (db.getType().equals(EnsemblDBType.compara)) {
884    
885                if (!this.comparaDBByDivision.containsKey(((DBComparisonDatabase)db).getComparisonDivision())) {
886                    this.comparaDBByDivision.put(((DBComparisonDatabase)db).getComparisonDivision(),
887                            new HashMap<String,DBComparisonDatabase> ());
888                }
889                this.comparaDBByDivision.get(((DBComparisonDatabase)db).getComparisonDivision()).put(
890                        db.getDBVersion(),(DBComparisonDatabase) db);
891    
892                }
893    
894            }
895            this.allDatabases.add(db);
896        }
897    
898        @Override
899        public Collection<DBCollection> getCollectionRegistriesByName(String name) {
900            if (name==null||name.isEmpty()) {
901                return new ArrayList<DBCollection>();
902            }
903            if (collectionNameDBVersionHash.containsKey(name)) {
904                return new ArrayList<DBCollection>(collectionNameDBVersionHash.get(name).values());
905            } else {
906                return new ArrayList<DBCollection>();
907            }
908        }
909    
910        @Override
911        public Collection<DBCollection> getCollectionsByDBVersion(String dbVersion) {
912    
913            Collection<DBCollection> out = new ArrayList<DBCollection>();
914            if (dbVersion==null||dbVersion.isEmpty()) {
915                return out;
916            }
917    
918            for (String name : this.collectionNameDBVersionHash.keySet()) {
919    
920                if (this.collectionNameDBVersionHash.get(name).containsKey(dbVersion)) {
921                    out.add(this.collectionNameDBVersionHash.get(name).get(dbVersion));
922                }
923            }
924            return out;
925        }
926    
927        @Override
928        public List<DBCollection> getCollections() {
929            return collections;
930        }
931    
932        @Override
933        public Collection<DBSpecies> getSpecies() {
934            return new ArrayList<DBSpecies>(speciesHash.values());
935        }
936    
937        @Override
938        public Collection<DBCollectionSpecies> getCollectionSpecies() {
939            return new ArrayList<DBCollectionSpecies>(collectionspeciesHash.values());
940        }
941    
942        @Override
943        public void addSpecies(String dbStyleName, Species species) {
944    
945            if (dbStyleName==null || dbStyleName.isEmpty() || species==null) {
946                return;
947            }
948    
949            if (species instanceof DBCollectionSpecies) {
950                this.collectionspeciesHash.put(dbStyleName, (DBCollectionSpecies) species);
951            } else {
952                this.speciesHash.put(dbStyleName, (DBSpecies) species);
953            }
954    
955        }
956    
957        @Override
958        public String getMostRecentDBVersion() {
959    
960            if (this.dbConnection != null 
961                    && this.dbConnection.getDatasourceStyle().equalsIgnoreCase("ensemblgenomes") ) {
962                return this.mostRecentGenomesVersion;
963            } else {
964                return this.mostRecentEnsemblVersion;
965            }
966        }
967    
968        public String getBriefRegistryReport() {
969            StringBuffer out = new StringBuffer();
970            if (this.regConfig==null) {
971                out.append("This Registry object has not been configured"+newline);
972                return out.toString();
973            }
974            out.append("Registry for: " + this.dbConnection.getConfigurationProperties().getProperty("url") + newline);
975            out.append("Highest configured release : " + this.mostRecentEnsemblVersion + newline);
976            out.append("Known schema versions: " + newline);
977            for (Integer i : knownSchemaVersions) {
978                out.append("\t" + i + newline);
979            }
980            out.append(dbConnection.report());
981    
982            if (!this.alreadyInitialized) {
983                out.append("This configured Registry has not yet been initialized"+newline);
984                return out.toString();
985            }
986    
987            if (tooNewDB.toString() != null && !tooNewDB.toString().isEmpty()) {
988                out.append("Some database releases were too recent for the current JEnsembl configuration:"
989                        + newline + tooNewDB.toString());
990            }
991            if (unknownDB.toString() != null && !unknownDB.toString().isEmpty()) {
992                out.append("Some database releases were not known in the current JEnsembl configuration:"
993                        + newline + unknownDB.toString());
994            }
995    
996    
997    
998            return out.toString();
999        }
1000    
1001        public TreeSet<Integer> getKnownSchemaVersions() {
1002            return knownSchemaVersions;
1003        }
1004    
1005        @Override
1006        public int getHighestEnsemblSchemaVersion() {
1007            return highestEnsemblVersion;
1008        }
1009    
1010        @Override
1011        public int getHighestDBVersion() {
1012            return highestVersion;
1013        }
1014    
1015        @Override
1016        public DataSource getDatasourceType() {
1017            return datasourceType;
1018        }
1019    
1020        @Override
1021        public DBDatabase makeDatabase(String db_name) throws ConfigurationException {
1022    
1023            if (db_name==null||db_name.isEmpty()) {
1024                throw new ConfigurationException("Invalid database name: "+db_name);
1025            }
1026     
1027            EnsemblDBType t = null;
1028    
1029            for (EnsemblDBType et : EnsemblDBType.getAllDatabaseTypes()) {
1030    
1031                if (db_name.contains("_collection_") && db_name.matches(new String(".+_" + et.toString() + "_\\d+.*"))) {
1032                    t=et;
1033                    break;
1034                }
1035    
1036                else if (db_name.matches(new String(".+_" + et.toString() + "_\\d+.*"))
1037                        || (et.toString().startsWith("ensembl_")&& db_name.contains(et.toString() + "_"))) {
1038                    t = et;
1039                }
1040            }
1041    
1042            if (t==null) {
1043                throw new ConfigurationException("Unrecognized database type for database name: "+db_name);
1044            }
1045    
1046    
1047            try {
1048                if (EnsemblDBType.getSingleSpeciesDatabaseTypes().contains(t)) {
1049                    if (t.equals(EnsemblDBType.core)) {
1050                        return new DBSingleSpeciesCoreDatabase(db_name, t, this);
1051                    } else {
1052                        //haven't implemented othersubtypes yet
1053                        return new DBSingleSpeciesDatabase(db_name, t, this);
1054                    }
1055                } else if (EnsemblDBType.getCollectionDatabaseTypes().contains(t)) {
1056                    if (t.equals(EnsemblDBType.collection_core)) {
1057                      return new DBCollectionCoreDatabase(db_name, t, this);
1058                    } else {
1059                      //haven't implemented other subtypes yet
1060                       return new DBCollectionDatabase(db_name, t, this);
1061                    }
1062                } else if (EnsemblDBType.getSpeciesComparisonDatabaseTypes().contains(t)) {
1063                    return new DBComparisonDatabase(db_name, t, this);
1064                } else {
1065                    throw new Exception("Unrecognized database type for database name: " + db_name);
1066                }
1067            } catch (Exception e) {
1068                throw new ConfigurationException(e.getMessage());
1069            }
1070    
1071        }
1072    
1073        //DAO methods
1074    
1075        private List<String> getDatabases() throws DAOException {
1076    
1077            List<String> outList = null;
1078            SqlSession session = null;
1079    
1080            try {
1081                session = sqlMapper.openSession();
1082                DatabaseMapper dm = session.getMapper(DatabaseMapper.class);
1083                outList = dm.getAllDatabaseNames();
1084            } catch (Exception e) {
1085                throw new DAOException("Failed to interrogate all Database Names", e);
1086            } finally {
1087                if (session != null) {
1088                    session.close();
1089                }
1090            }
1091    
1092            if (outList == null) {
1093                /* A null tempList is a perfectly valid outcome to return */
1094                return new ArrayList<String>();
1095            }
1096    
1097            return outList;
1098        }
1099    
1100        private DBCollection getCollectionSpeciesProperties(CollectionCoreDatabase database) throws DAOException {
1101    
1102            DBCollection collection = null;
1103            DBCollectionCoreDatabase myDatabase = (DBCollectionCoreDatabase) database;
1104            String dBName = myDatabase.dBName;
1105            String schemaVersion = myDatabase.getSchemaVersion();
1106            String dbVersion = myDatabase.getDBVersion();
1107            List<DBCollectionSpecies> out = new ArrayList<DBCollectionSpecies>();
1108            TreeMap<Integer, DBCollectionSpecies> localSpp = new TreeMap<Integer, DBCollectionSpecies>();
1109            collection = new DBCollection(myDatabase);
1110    
1111            List<HashMap> results = null;
1112            SqlSession session = null;
1113    
1114            try {
1115                session = sqlMapper.openSession();
1116                DatabaseMapper dm = session.getMapper(DatabaseMapper.class);
1117                results = dm.getSpeciesFromCollection(dBName);
1118            } catch (Exception e) {
1119                throw new DAOException("Failed to interrogate species properties for " + dBName, e);
1120            } finally {
1121                if (session != null) {
1122                    session.close();
1123                }
1124            }
1125    
1126            if ((results == null) || (results.isEmpty() == true)) {
1127                /*  return empty collectiont*/
1128                return collection;
1129            }
1130    
1131            HashMap<Integer, HashMap<String, String>> buildLevelsHash = new HashMap<Integer, HashMap<String, String>>();
1132    
1133            for (Object o : results) {
1134    
1135                Integer id = null;
1136                DBCollectionSpecies species = null;
1137    
1138                HashMap m = (HashMap) o;
1139                m.put("schemaVersion", schemaVersion);
1140    
1141                id = (Integer) m.get("species_id");
1142    
1143                // if we've already made species with this id  for this collection
1144                //use it
1145                if (localSpp.containsKey(id)) {
1146                    species = localSpp.get(id);
1147                }
1148                //we haven't got a species with this id in the collection already
1149                //- so make one, add it, and use it
1150                else {
1151                    try {
1152                        species = new DBCollectionSpecies(myDatabase);
1153                    } catch (ConfigurationException ex) {
1154                        //what do we do here??
1155                    }
1156                    if (species==null) {
1157                        continue;
1158                    }
1159                    species.setIDForVersion(id, dbVersion);
1160                    localSpp.put(id, species);
1161                }
1162    
1163                if (!((String) m.get("meta_key")).endsWith("build.level")) {
1164                    species.setProperty(m);
1165                } else {
1166    
1167                    if (buildLevelsHash.containsKey(id)) {
1168                        buildLevelsHash.get(id).put((String) m.get("meta_key"), (String) m.get("meta_value"));
1169                    } else {
1170                        buildLevelsHash.put(id, new HashMap<String, String>());
1171                        buildLevelsHash.get(id).put((String) m.get("meta_key"), (String) m.get("meta_value"));
1172                    }
1173                }
1174    
1175                if (species.getCurrentCoreDatabase() == null
1176                        && myDatabase.getType().equals(EnsemblDBType.collection_core)
1177                        && dbVersion.equalsIgnoreCase(this.getMostRecentDBVersion())) {
1178                    species.setCurrentCoreDatabase(myDatabase);
1179                }
1180            }
1181    
1182            for (DBCollectionSpecies s : localSpp.values()) {
1183                //this cant be used cos we havent populated the alias look up yet!
1184                //if (this.registry.getSpeciesByAlias(s.getDatabaseStyleName()) == null) {
1185    
1186    
1187                //ensembl have changed the case of the first letter of the dbname between v58 & v59
1188                //therefore the code below fails to rationalize species between collections 58 and 59
1189                //i am just going to live with this for the time being bcause the dbname is also used as the comparaname
1190                //and is also different between 58 and 59
1191                //hopefully from 59 things will be stable
1192    
1193    
1194    
1195                //give this to the reg
1196    
1197                if (this.getSpeciesByEnsemblName(s.getDatabaseStyleName()) == null) {
1198                    //we've made a new species so add itto the registry
1199                    this.addSpecies(s.getDatabaseStyleName(), s);
1200                    //and add it to this collection
1201                    collection.addSpecies(s);
1202                } else {
1203                    //we've already got this species in the registry - so modify it there
1204                    DBCollectionSpecies existingSpecies = (DBCollectionSpecies) this.getSpeciesByEnsemblName(s.getDatabaseStyleName());
1205                    existingSpecies.getAliases().addAll(s.getAliases());
1206                    existingSpecies.setIDForVersion(s.getDBSpeciesID(dbVersion), dbVersion);
1207                    existingSpecies.addDatabase(myDatabase);
1208                    if (existingSpecies.getCurrentCoreDatabase() == null
1209                            && s.getCurrentCoreDatabase() != null) {
1210                        existingSpecies.setCurrentCoreDatabase(s.getCurrentCoreDatabase());
1211                    }
1212                    //and add it to this collection
1213                    collection.addSpecies(existingSpecies);
1214                }
1215            }
1216    
1217            myDatabase.setCollection(collection);
1218    
1219            for (DBSpecies s : collection.getSpecies()) {
1220                DBCollectionSpecies sp = (DBCollectionSpecies) s;
1221                if (buildLevelsHash.containsKey(sp.getDBSpeciesID(dbVersion))) {
1222                    myDatabase.setBuildLevels(sp, buildLevelsHash.get(sp.getDBSpeciesID(dbVersion)));
1223                    HashMap<String, String> map = buildLevelsHash.get(sp.getDBSpeciesID(dbVersion));
1224                }
1225            }
1226    
1227            return collection;
1228        }
1229    
1230        private List<String> getAllCoreDatabasesForVersion(int dbVersion) throws DAOException {
1231    
1232            int release = dbVersion;
1233            List<String> outList = null;
1234            SqlSession session = null;
1235    
1236            try {
1237                session = sqlMapper.openSession();
1238                DatabaseMapper dm = session.getMapper(DatabaseMapper.class);
1239                outList = dm.getAllCoreDatabaseNames(release);
1240            } catch (Exception e) {
1241                throw new DAOException("Failed to interrogate all core Database Names for release " + release, e);
1242            } finally {
1243                if (session != null) {
1244                    session.close();
1245                }
1246            }
1247    
1248            if (outList == null || outList.isEmpty()) {
1249                /* A null List is a perfectly valid outcome to return */
1250                return null;
1251            }
1252    
1253            return outList;
1254        }
1255    
1256        public void setCoreDBBuildLevels(SingleSpeciesCoreDatabase database) throws DAOException {
1257            
1258            List<HashMap> tempList = null;
1259    
1260            SqlSession session = null;
1261    
1262            try {
1263                session = sqlMapper.openSession();
1264                DatabaseMapper dm = session.getMapper(DatabaseMapper.class);
1265                tempList = dm.getSpeciesProperties(database.getdBName());
1266            } catch (Exception e) {
1267                throw new DAOException("Failed to interrogate db "+database.getdBName()+" for build levels", e);
1268            } finally {
1269                if (session != null) {
1270                    session.close();
1271                }
1272            }
1273            
1274            if ((tempList == null) || (tempList.isEmpty() == true)) {
1275                return ;
1276            }
1277            
1278            Iterator it = tempList.iterator();
1279    
1280            while (it.hasNext()) {
1281                HashMap row = (HashMap) it.next();
1282    
1283                String key = (String) row.get("key");
1284                String value = (String) row.get("value");
1285    
1286                if (key==null || key.isEmpty() || value==null) {
1287                    continue;
1288                }
1289    
1290                if (key.endsWith("build.level")) {
1291                    database.setBuildLevel(key, value);
1292                } 
1293    
1294            }
1295    
1296        }
1297    
1298        private DBSpecies getSpeciesProperties(SingleSpeciesCoreDatabase database) throws DAOException {
1299    
1300            DBSpecies spData = new DBSpecies((DBSingleSpeciesCoreDatabase) database);
1301    
1302            List<HashMap> tempList = null;
1303    
1304            SqlSession session = null;
1305    
1306            try {
1307                session = sqlMapper.openSession();
1308                DatabaseMapper dm = session.getMapper(DatabaseMapper.class);
1309                tempList = dm.getSpeciesProperties(database.getdBName());
1310            } catch (Exception e) {
1311                throw new DAOException("Failed to interrogate species properties for " + spData.getDatabaseStyleName(), e);
1312            } finally {
1313                if (session != null) {
1314                    session.close();
1315                }
1316            }
1317    
1318            //for pre dbVersion 59 releases, the meta table is not guaranteed
1319            //to hold the species.production_name, species.short_name and
1320            //species.scientific_name meta_keys
1321    
1322            //pre schemaVersion 59 the compara name was always = Species Binomial
1323            //post schemaVersion 58 the compara name - production name
1324    
1325            if (spData.getDatabaseStyleName().isEmpty()) {
1326                spData.setDatabaseStyleSpeciesName(database.getDbSpeciesName());
1327                spData.getAliases().add(spData.getDatabaseStyleName());
1328            }
1329    
1330            if (spData.getSpeciesBinomial().isEmpty()) {
1331                String s = database.getDbSpeciesName();
1332                spData.setSpeciesBinomial( s.replaceFirst( s.substring(0, 1), (s.substring(0,1)).toUpperCase() ).replace("_"," "));
1333                spData.getAliases().add(spData.getSpeciesBinomial());
1334            }
1335    
1336            if ((tempList == null) || (tempList.isEmpty() == true)) {
1337                return spData;
1338            }
1339    
1340            Iterator it = tempList.iterator();
1341    
1342            while (it.hasNext()) {
1343                HashMap row = (HashMap) it.next();
1344    
1345                String key = (String) row.get("key");
1346                String value = (String) row.get("value");
1347    
1348                if (key==null || key.isEmpty() || value==null) {
1349                    continue;
1350                }
1351    
1352                if (key.equals("species.stable_id_prefix")) {
1353                    spData.setEnsemblStablePrefix(value);
1354                } else if (key.equals("species.production_name")) {
1355                    spData.setDatabaseStyleSpeciesName(value);
1356                    spData.getAliases().add(value);
1357                } else if (key.equals("species.common_name")) {
1358                    spData.getAliases().add(value);
1359                    spData.setCommonName(value);
1360                } else if (key.equals("species.taxonomy_id")) {
1361                    spData.getAliases().add(value);
1362                    spData.setTaxonomyID(value);
1363                } else if (key.equals("species.short_name")) {
1364                    spData.getAliases().add(value);
1365                    spData.setShortName(value);
1366                } else if (key.equals("species.alias")
1367                        || key.equals("species.ensembl_common_name")
1368                        || key.equals("species.ensembl_alias_name")) {
1369                    spData.getAliases().add(value);
1370                } else if (key.endsWith("build.level")) {
1371                    database.setBuildLevel(key, value);
1372                } else if (key.equals("species.division")) {
1373                    spData.setComparaDivision(value);
1374                }
1375    
1376            }
1377    
1378            if (Integer.parseInt(database.getSchemaVersion()) >= 59   ) {
1379                spData.setComparaName(spData.getDatabaseStyleName());
1380            } else {
1381                spData.setComparaName(spData.getSpeciesBinomial());
1382            }
1383    
1384            return spData;
1385        }
1386    
1387        @Override
1388        public String getAssembly(SingleSpeciesDatabase database) throws DAOException {
1389    
1390            if (database== null || database.getdBName()==null || database.getdBName().isEmpty()) {
1391                return "";
1392            }
1393    
1394            //for current Databases this query will be cached by mybatis
1395            //cos it was used to make the species
1396    
1397            List<HashMap> tempList = null;
1398    
1399            SqlSession session = null;
1400    
1401            try {
1402                session = sqlMapper.openSession();
1403                DatabaseMapper dm = session.getMapper(DatabaseMapper.class);
1404                tempList = dm.getSpeciesProperties(database.getdBName());
1405            } catch (Exception e) {
1406                throw new DAOException("Failed to retrieve assembly name for " + database.getdBName(), e);
1407            } finally {
1408                if (session != null) {
1409                    session.close();
1410                }
1411            }
1412    
1413    
1414    
1415            if ((tempList == null) || (tempList.isEmpty() == true)) {
1416                return "";
1417            }
1418    
1419            Iterator it = tempList.iterator();
1420    
1421            while (it.hasNext()) {
1422                HashMap row = (HashMap) it.next();
1423    
1424                String key = (String) row.get("key");
1425                String value = (String) row.get("value");
1426    
1427                if (key==null || key.isEmpty() || value==null) {
1428                    continue;
1429                }
1430    
1431                if (key.equals("assembly.name")) {
1432                    return value;
1433                }
1434    
1435            }
1436    
1437            return "";
1438        }
1439    
1440        @Override
1441        public HashMap<CollectionSpecies,String> getAssemblies(CollectionDatabase database) throws DAOException {
1442    
1443            HashMap<CollectionSpecies,String> out = new HashMap<CollectionSpecies,String>();
1444    
1445            if (database== null || database.getdBName()==null || database.getdBName().isEmpty()
1446                    || database.getCollection()==null || database.getCollection().getSpecies().isEmpty()) {
1447                return out;
1448            }
1449    
1450            TreeSet<? extends CollectionSpecies> spp = database.getCollection().getSpecies();
1451    
1452            HashMap<Integer, DBCollectionSpecies> localSpp = new HashMap<Integer, DBCollectionSpecies>();
1453    
1454            for (CollectionSpecies sp : spp) {
1455                localSpp.put(sp.getDBSpeciesID(database.getDBVersion()), (DBCollectionSpecies) sp);
1456            }
1457    
1458            String dBName = database.getdBName();
1459            List<HashMap> results = null;
1460            SqlSession session = null;
1461    
1462            try {
1463                session = sqlMapper.openSession();
1464                DatabaseMapper dm = session.getMapper(DatabaseMapper.class);
1465                results = dm.getSpeciesFromCollection(dBName);
1466            } catch (Exception e) {
1467                throw new DAOException("Failed to get assembly names for " + dBName, e);
1468            } finally {
1469                if (session != null) {
1470                    session.close();
1471                }
1472            }
1473    
1474            if ((results == null) || (results.isEmpty() == true)) {
1475                /*  return empty collectiont*/
1476                return out;
1477            }
1478    
1479    
1480            for (Object o : results) {
1481    
1482                Integer id = null;
1483                DBCollectionSpecies species = null;
1484    
1485                HashMap m = (HashMap) o;
1486    
1487                id = (Integer) m.get("species_id");
1488    
1489                // if we've already made species with this id  for this collection
1490                //use it
1491                if (localSpp.containsKey(id)) {
1492                    species = localSpp.get(id);
1493                } else {
1494                    continue;
1495                }
1496    
1497                if ( m.get("meta_key").equals("assembly.name") ) {
1498                    out.put(species, (String) m.get("meta_value"));
1499                }
1500            }
1501    
1502    
1503            return out;
1504        }
1505    
1506    
1507    }