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 (version 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 021 package uk.ac.roslin.ensembl.dao.database; 022 023 import java.util.ArrayList; 024 import java.util.HashMap; 025 import java.util.Iterator; 026 import java.util.List; 027 import java.util.Set; 028 import java.util.TreeMap; 029 import uk.ac.roslin.ensembl.datasourceaware.core.DAChromosome; 030 import uk.ac.roslin.ensembl.datasourceaware.core.DACoordinateSystem; 031 import uk.ac.roslin.ensembl.dao.database.factory.DBDAOCollectionCoreFactory; 032 import uk.ac.roslin.ensembl.dao.database.factory.DBDAOCollectionFactory; 033 import uk.ac.roslin.ensembl.exception.ConfigurationException; 034 import uk.ac.roslin.ensembl.exception.DAOException; 035 import uk.ac.roslin.ensembl.model.ObjectType; 036 import uk.ac.roslin.ensembl.model.core.CoordinateSystem; 037 import uk.ac.roslin.ensembl.model.core.Species; 038 import uk.ac.roslin.ensembl.model.database.CollectionCoreDatabase; 039 import uk.ac.roslin.ensembl.model.core.CollectionSpecies; 040 import uk.ac.roslin.ensembl.config.EnsemblCoordSystemType; 041 import uk.ac.roslin.ensembl.config.EnsemblDBType; 042 import uk.ac.roslin.ensembl.config.FeatureType; 043 import uk.ac.roslin.ensembl.model.database.Registry; 044 045 /** 046 * 047 * @author paterson 048 */ 049 public class DBCollectionCoreDatabase extends DBCollectionDatabase implements CollectionCoreDatabase { 050 051 052 private TreeMap<DBCollectionSpecies, TreeMap<Integer, DACoordinateSystem>> CSHash = new TreeMap<DBCollectionSpecies, TreeMap<Integer, DACoordinateSystem>>(); 053 054 private TreeMap<DBCollectionSpecies, DACoordinateSystem> seqLevelCSHash = new TreeMap<DBCollectionSpecies, DACoordinateSystem>(); 055 private TreeMap<DBCollectionSpecies, DACoordinateSystem> chrLevelCSHash = new TreeMap<DBCollectionSpecies, DACoordinateSystem>(); 056 private TreeMap<DBCollectionSpecies, DACoordinateSystem> topLevelCSHash = new TreeMap<DBCollectionSpecies, DACoordinateSystem>(); 057 058 private TreeMap<DBCollectionSpecies, DBDAOCollectionCoreFactory> factoryHash = new TreeMap<DBCollectionSpecies, DBDAOCollectionCoreFactory>(); 059 060 private TreeMap<DBCollectionSpecies, HashMap<FeatureType, HashMap<DACoordinateSystem, Integer>>> featureCSHash 061 = new TreeMap<DBCollectionSpecies, HashMap<FeatureType, HashMap<DACoordinateSystem, Integer>>>(); 062 063 private TreeMap<DBCollectionSpecies, HashMap<DACoordinateSystem, List<FeatureType>>> CSFeatureHash 064 = new TreeMap<DBCollectionSpecies, HashMap<DACoordinateSystem, List<FeatureType>>>(); 065 066 067 // private TreeMap<DBCollectionSpecies, String> speciesGeneBuildLevelHash = new TreeMap<DBCollectionSpecies, String>(); 068 // private TreeMap<DBCollectionSpecies, String> speciesExonBuildLevelHash = new TreeMap<DBCollectionSpecies, String>(); 069 // private TreeMap<DBCollectionSpecies, String> speciesTranscriptBuildLevelHash = new TreeMap<DBCollectionSpecies, String>(); 070 071 private TreeMap<DBCollectionSpecies, HashMap<FeatureType, String>> speciesBuildLevels = new TreeMap<DBCollectionSpecies, HashMap<FeatureType,String>>(); 072 073 public DBCollectionCoreDatabase(String db_name, EnsemblDBType type, Registry registry) throws ConfigurationException { 074 super(db_name, type, registry); 075 } 076 077 078 @Override 079 public DBDAOCollectionCoreFactory getCoreFactory(Species sp) { 080 081 082 083 if (sp == null || collection ==null || !this.collection.getSpecies().contains(sp)) { 084 return null; 085 } 086 087 DBCollectionSpecies species = (DBCollectionSpecies) sp; 088 089 if (this.factoryHash.containsKey(species)) { 090 return this.factoryHash.get(species); 091 } else { 092 DBDAOCollectionCoreFactory f = null; 093 094 try { 095 f = (DBDAOCollectionCoreFactory) DBDAOCollectionFactory.makeFactory(this, species); 096 this.factoryHash.put(species, f); 097 } catch (Exception ex) { 098 } 099 return f; 100 101 } 102 } 103 104 @Override 105 public DACoordinateSystem getChromosomeLevelCS(Species species) throws DAOException { 106 107 if (species == null || this.collection == null || !this.getCollection().getSpecies().contains(species)) { 108 return null; 109 } 110 111 DBCollectionSpecies sp = (DBCollectionSpecies) species; 112 113 if (!this.chrLevelCSHash.containsKey(sp)) { 114 this.lazyLoadCoordinateSytems(sp); 115 } 116 117 return this.chrLevelCSHash.get(sp); 118 119 } 120 121 @Override 122 public DACoordinateSystem getSequenceLevelCS(Species species) throws DAOException { 123 124 if (species == null || this.collection == null || !this.getCollection().getSpecies().contains(species)) { 125 return null; 126 } 127 DBCollectionSpecies sp = (DBCollectionSpecies) species; 128 if (!this.seqLevelCSHash.containsKey(sp)) { 129 this.lazyLoadCoordinateSytems(sp); 130 } 131 132 return this.seqLevelCSHash.get(sp); 133 } 134 135 @Override 136 public DACoordinateSystem getTopLevelCS(Species species) throws DAOException { 137 138 if ( species == null || this.collection == null || !this.getCollection().getSpecies().contains(species)) { 139 return null; 140 } 141 DBCollectionSpecies sp = (DBCollectionSpecies) species; 142 if (!this.topLevelCSHash.containsKey(sp)) { 143 this.lazyLoadCoordinateSytems(sp); 144 } 145 146 return this.topLevelCSHash.get(sp); 147 } 148 149 150 private List<DACoordinateSystem> fetchCS(DBCollectionSpecies species) throws DAOException { 151 152 List<DACoordinateSystem> coords = new ArrayList<DACoordinateSystem>(); 153 if (species == null || collection ==null || !this.collection.getSpecies().contains(species)) { 154 return coords; 155 } 156 157 //can throw DAOException 158 if ( this.getCoreFactory(species)!=null) { 159 coords = this.getCoreFactory(species).getCoordinateSystemDAO(). 160 getCoordinateSystems(); 161 } else { 162 return coords; 163 } 164 return coords; 165 } 166 167 168 private void lazyLoadCoordinateSytems(DBCollectionSpecies species) throws DAOException { 169 170 if (species == null || collection ==null || !this.collection.getSpecies().contains(species)) { 171 return ; 172 } 173 174 List<DACoordinateSystem> coords = this.fetchCS(species); 175 176 if (!coords.isEmpty()) { 177 this.setCoordinateSytems(species, coords); 178 } 179 180 //set null values to prevent repeating lazy load 181 182 if (!this.chrLevelCSHash.containsKey(species)) { 183 this.chrLevelCSHash.put(species, null); 184 } 185 if (!this.topLevelCSHash.containsKey(species)) { 186 this.topLevelCSHash.put(species, null); 187 } 188 if (!this.seqLevelCSHash.containsKey(species)) { 189 this.seqLevelCSHash.put(species, null); 190 } 191 192 } 193 194 private void setCoordinateSytems(DBCollectionSpecies species, List<DACoordinateSystem> coords ) throws DAOException { 195 196 if (species == null || collection ==null || !this.collection.getSpecies().contains(species)) { 197 return ; 198 } 199 200 TreeMap<Integer, DACoordinateSystem> hash1 = new TreeMap<Integer, DACoordinateSystem>(); 201 202 203 //set the is for the top, chromosome and sequence levels 204 205 for (DACoordinateSystem cs: coords) { 206 207 hash1.put(cs.getId(), cs); 208 209 if (cs.getRank()==1) { 210 211 this.topLevelCSHash.put(species, cs); 212 213 if (cs.getType()==EnsemblCoordSystemType.chromosome) { 214 this.chrLevelCSHash.put(species, cs); 215 } 216 } 217 218 if (cs.isSequenceLevel()) { 219 this.seqLevelCSHash.put(species, cs); 220 } 221 } 222 223 this.CSHash.put(species, hash1); 224 225 //if the top rank wasnt chromosome level, find the highest ranked chromosome level 226 227 if (!this.chrLevelCSHash.containsKey(species)) { 228 229 TreeMap <Integer, DACoordinateSystem> temp = new TreeMap <Integer, DACoordinateSystem>(); 230 231 for (DACoordinateSystem cs: coords) { 232 temp.put(cs.getRank(), cs); 233 } 234 235 Iterator<Integer> it = temp.keySet().iterator(); 236 while (it.hasNext()) { 237 DACoordinateSystem cs = temp.get(it.next()); 238 if (cs.getType()==EnsemblCoordSystemType.chromosome) { 239 this.chrLevelCSHash.put(species, cs); 240 break; 241 } 242 } 243 } 244 } 245 246 @Override 247 public void setBuildLevels(Species species, HashMap<String, String> keyedValues) { 248 249 if (species == null || collection ==null || !this.collection.getSpecies().contains(species)) { 250 return ; 251 } 252 253 HashMap<FeatureType, String> map = new HashMap<FeatureType, String>(); 254 255 for (String key : keyedValues.keySet() ) { 256 257 String temp = key.replace("build.level", ""); 258 259 if (FeatureType.getFeatureType(temp)!= null ) { 260 map.put(FeatureType.getFeatureType(temp), keyedValues.get(key)); 261 } 262 263 } 264 265 this.speciesBuildLevels.put((DBCollectionSpecies) species, map); 266 } 267 268 @Override 269 @SuppressWarnings("element-type-mismatch") 270 public String getBuildLevel(Species species, String featureKey) throws DAOException{ 271 272 if (species == null || collection ==null || !this.collection.getSpecies().contains(species)) { 273 return null; 274 } 275 276 String out = null; 277 278 if (this.speciesBuildLevels.get(species)!= null) { 279 out = this.speciesBuildLevels.get(species).get(FeatureType.getFeatureType(featureKey)); 280 } 281 return out; 282 } 283 284 //dont really want this public - just for testing 285 public HashMap<FeatureType, String> getBuildLevels(CollectionSpecies species) { 286 if (species == null || collection ==null || !this.collection.getSpecies().contains(species)) { 287 return null; 288 } 289 return this.speciesBuildLevels.get(species); 290 } 291 292 private void setFeatureCSHash(DBCollectionSpecies sp) throws DAOException { 293 294 if (sp == null || collection ==null || !this.collection.getSpecies().contains(sp)) { 295 return; 296 } 297 298 if (!this.CSHash.containsKey(sp)) { 299 this.lazyLoadCoordinateSytems(sp); 300 } 301 302 303 HashMap<DACoordinateSystem, List<FeatureType>> hash1 = new HashMap<DACoordinateSystem, List<FeatureType>>(); 304 305 for (DACoordinateSystem c : this.CSHash.get(sp).values()) { 306 hash1.put(c, new ArrayList<FeatureType>()); 307 308 } 309 310 this.CSFeatureHash.put(sp, hash1); 311 312 this.featureCSHash.put(sp, new HashMap<FeatureType, HashMap<DACoordinateSystem, Integer>>() ); 313 314 try { 315 316 this.getCoreFactory(sp).getCoordinateSystemDAO().setFeatureCS(); 317 318 } catch (DAOException e) { 319 throw e; 320 } 321 322 } 323 324 @Override 325 public void addFeatureCS(String featureType, Integer csID, Integer maxLength, Species sp) { 326 327 if (sp == null || collection ==null || !this.collection.getSpecies().contains(sp)) { 328 return ; 329 } 330 331 FeatureType localType = null; 332 DACoordinateSystem cs = null; 333 334 localType = FeatureType.getFeatureType(featureType); 335 cs = this.CSHash.get(sp).get(csID); 336 337 if (localType == null || cs == null) { 338 return; 339 } else { 340 if (!this.featureCSHash.get(sp).containsKey(localType)) { 341 this.featureCSHash.get(sp).put(localType, new HashMap<DACoordinateSystem, Integer>()); 342 } 343 this.featureCSHash.get(sp).get(localType).put(cs, maxLength); 344 345 this.CSFeatureHash.get(sp).get(cs).add(localType); 346 347 } 348 349 350 } 351 352 353 @Override 354 public Set<DACoordinateSystem> getCSForFeature(Species sp, ObjectType feature) throws DAOException { 355 356 if (sp == null || collection ==null || !this.collection.getSpecies().contains(sp)) { 357 return null; 358 } 359 360 if (!this.featureCSHash.containsKey(sp)) { 361 this.setFeatureCSHash((DBCollectionSpecies) sp); 362 } 363 364 365 if (this.featureCSHash.containsKey(sp) 366 && this.featureCSHash.get(sp).containsKey(feature)) { 367 return this.featureCSHash.get(sp).get(feature).keySet(); 368 } else { 369 370 return null; 371 } 372 } 373 374 @Override 375 public List<FeatureType> getFeaturesForCS(Species sp, CoordinateSystem coordSys) throws DAOException { 376 377 if (sp== null || collection ==null || !this.collection.getSpecies().contains(sp)) { 378 return null; 379 } 380 381 if (!this.featureCSHash.containsKey(sp)) { 382 this.setFeatureCSHash((DBCollectionSpecies) sp); 383 } 384 385 if (this.CSFeatureHash.containsKey(sp) 386 && this.CSFeatureHash.get(sp).containsKey(coordSys)) { 387 return this.CSFeatureHash.get(sp).get(coordSys); 388 } else { 389 return null; 390 } 391 } 392 393 @Override 394 public Integer getMaxLengthForFeature(Species sp, ObjectType feature, CoordinateSystem cs) throws DAOException { 395 396 if (sp == null || collection ==null || !this.collection.getSpecies().contains(sp)) { 397 return null; 398 } 399 400 if ( feature == null || cs == null ) { 401 return null; 402 } 403 404 if (!this.featureCSHash.containsKey(sp) ) { 405 this.setFeatureCSHash((DBCollectionSpecies) sp); 406 } 407 408 if (this.featureCSHash.containsKey(sp) 409 && this.featureCSHash.get(sp).containsKey(feature) 410 && this.featureCSHash.get(sp).get(feature).containsKey(cs)) { 411 return this.featureCSHash.get(sp).get(feature).get(cs); 412 } else { 413 return null; 414 } 415 416 } 417 418 @Override 419 public DACoordinateSystem getBuildCoordSystem(Species species, String featureType) throws DAOException{ 420 421 if (species == null || collection ==null || !this.collection.getSpecies().contains(species) 422 || this.speciesBuildLevels.get(species) == null || 423 featureType ==null || featureType.isEmpty()) { 424 return null; 425 } 426 427 if (FeatureType.getFeatureType(featureType) != null) { 428 String level = this.speciesBuildLevels.get(species).get(FeatureType.getFeatureType(featureType)); 429 if (level.equalsIgnoreCase("toplevel")) { 430 return this.topLevelCSHash.get(species); 431 } else { 432 return null; 433 } 434 435 // //are there other values possible? 436 // else if (level.equalsIgnoreCase("chromosomelevel")) { 437 // return this.getChromosomeLevelCoordSystem(); 438 // } else if (level.equalsIgnoreCase("sequencelevel")) { 439 // return this.getSequenceLevelCoordSystem(); 440 // } 441 } 442 443 return null; 444 } 445 446 @Override 447 public DACoordinateSystem getCSByID(Species species, Integer id) throws DAOException{ 448 449 if (species == null || collection ==null || !this.collection.getSpecies().contains(species) 450 || id == null) { 451 return null; 452 } 453 454 DACoordinateSystem out = null; 455 if (!this.CSHash.containsKey(species)) { 456 457 //lazyload can throw DAOException 458 this.lazyLoadCoordinateSytems((DBCollectionSpecies) species); 459 460 } 461 462 out = this.CSHash.get(species).get(id); 463 464 return out; 465 } 466 467 @Override 468 public DAChromosome getChromosomeByName(Species species, String name) throws DAOException { 469 470 if (species == null || collection ==null || !this.collection.getSpecies().contains(species)) { 471 return null; 472 } 473 474 return this.getCoreFactory(species).getChromosomeDAO().getChromosomeByName(name); 475 476 } 477 478 @Override 479 public List<DAChromosome> getChromosomes(Species species) throws DAOException { 480 481 if (species == null || collection ==null || !this.collection.getSpecies().contains(species)) { 482 return null; 483 } 484 485 return this.getCoreFactory(species).getChromosomeDAO().getChromosomes(); 486 487 } 488 489 490 }