001/** 002 * Copyright (C) 2010-2015 The Roslin Institute <contact andy.law@roslin.ed.ac.uk> 003 * 004 * This file is part of JEnsembl: a Java API to Ensembl data sources developed by the 005 * Bioinformatics Group at The Roslin Institute, The Royal (Dick) School of 006 * Veterinary Studies, University of Edinburgh. 007 * 008 * Project hosted at: http://jensembl.sourceforge.net 009 * 010 * This is free software: you can redistribute it and/or modify 011 * it under the terms of the GNU General Public License (version 3) as published by 012 * the Free Software Foundation. 013 * 014 * This software is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public License 020 * in this software distribution. If not, see: http://opensource.org/licenses/gpl-3.0.html 021 */ 022package uk.ac.roslin.ensembl.dao.database.coreaccess; 023 024import java.util.ArrayList; 025import java.util.HashMap; 026import java.util.List; 027import java.util.TreeMap; 028import org.apache.ibatis.session.SqlSession; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031import uk.ac.roslin.ensembl.config.AssemblyExceptionType; 032import uk.ac.roslin.ensembl.config.EnsemblCoordSystemType; 033import uk.ac.roslin.ensembl.dao.coreaccess.ChromosomeDAO; 034import uk.ac.roslin.ensembl.dao.factory.DAOCollectionCoreFactory; 035import uk.ac.roslin.ensembl.dao.factory.DAOCoreFactory; 036import uk.ac.roslin.ensembl.dao.factory.DAOSingleSpeciesCoreFactory; 037import uk.ac.roslin.ensembl.datasourceaware.core.DAAssembledDNASequence; 038import uk.ac.roslin.ensembl.datasourceaware.core.DAChromosome; 039import uk.ac.roslin.ensembl.datasourceaware.core.DADNASequence; 040import uk.ac.roslin.ensembl.datasourceaware.core.DAGene; 041import uk.ac.roslin.ensembl.exception.DAOException; 042import uk.ac.roslin.ensembl.mapper.core.ChromosomeMapper; 043import uk.ac.roslin.ensembl.mapper.handler.DBResultHandler; 044import uk.ac.roslin.ensembl.model.Coordinate; 045import uk.ac.roslin.ensembl.model.Mapping; 046import uk.ac.roslin.ensembl.model.core.Chromosome; 047import uk.ac.roslin.ensembl.model.core.CoordinateSystem; 048 049/** 050 * 051 * @author paterson 052 */ 053public class DBChromosomeDAO extends DBCoreObjectDAO implements ChromosomeDAO { 054 055 final static Logger LOGGER = LoggerFactory.getLogger(DBChromosomeDAO.class); 056 057 public DBChromosomeDAO() { 058 super(); 059 } 060 061 public DBChromosomeDAO(DAOSingleSpeciesCoreFactory factory) { 062 super(factory); 063 } 064 065 public DBChromosomeDAO(DAOCollectionCoreFactory factory) { 066 super(factory); 067 } 068 069 @Override 070 public DAChromosome getChromosomeByName(String name) throws DAOException { 071 072 if (name==null || name.isEmpty()) { 073 return null; 074 } 075 076 DAChromosome out = null; 077 String chrName = name; 078 CoordinateSystem chrCS = null; 079 080 if (singleSpecies) { 081 chrCS = ssFactory.getDatabase().getChromosomeLevelCoordSystem(); 082 } else { 083 chrCS = collFactory.getDatabase().getChromosomeLevelCS(species); 084 } 085 086 if (chrCS==null || chrCS.getId()==null ) { 087 throw new DAOException("Failed to call to retrieve the CoordinateSystem for Chromosomes"); 088 } 089 090 Integer chrCSID = chrCS.getId(); 091 092 HashMap parameters = new HashMap(); 093 parameters.put("chrName",chrName); 094 parameters.put("coordSysID", chrCSID); 095 096 SqlSession session = null; 097 098 try { 099 session = this.getFactory().getNewSqlSession(); 100 ChromosomeMapper mapper = session.getMapper(ChromosomeMapper.class); 101 out = mapper.getChromosomeByName_CoordSysID(parameters); 102 } catch (Exception e) { 103 throw new DAOException("Failed to call getChromsomeByName_CoordSysID", e); 104 } finally { 105 if (session != null) { 106 session.close(); 107 } 108 } 109 110 if (out != null) { 111 out.setDaoFactory(daoFactory); 112 out.setCoordSystem(chrCS); 113 out.setSpecies(species); 114 } 115 116 return out; 117 } 118 119 @Override 120 public DAAssembledDNASequence getFragmentByName(String name) throws DAOException { 121 122 if (name==null || name.isEmpty()) { 123 return null; 124 } 125 126 DAAssembledDNASequence out = null; 127 String assName = name; 128 CoordinateSystem topCS = null; 129 130 if (singleSpecies) { 131 topCS = ssFactory.getDatabase().getTopLevelCoordSystem(); 132 } else { 133 topCS = collFactory.getDatabase().getTopLevelCS(species); 134 } 135 136 if (topCS==null || topCS.getId()==null ) { 137 throw new DAOException("Failed to call to retrieve the CoordinateSystem for TopLevel"); 138 } 139 140 Integer topCSID = topCS.getId(); 141 142 HashMap parameters = new HashMap(); 143 parameters.put("coordSysID", topCSID); 144 145 parameters.put("assName",assName); 146 147 148 SqlSession session = null; 149 150 try { 151 session = this.getFactory().getNewSqlSession(); 152 ChromosomeMapper mapper = session.getMapper(ChromosomeMapper.class); 153 out = mapper.getTopLevelFragmentByName_CoordSysID(parameters); 154 } catch (Exception e) { 155 throw new DAOException("Failed to call getTopLevelFragmentByName_CoordSysID", e); 156 } finally { 157 if (session != null) { 158 session.close(); 159 } 160 } 161 162 if (out != null) { 163 out.setDaoFactory(daoFactory); 164 out.setCoordSystem(topCS); 165 out.setSpecies(species); 166 } 167 168 return out; 169 } 170 171 @Override 172 public List<DAChromosome> getChromosomes() throws DAOException { 173 174 List<DAChromosome> out = new ArrayList<DAChromosome>(); 175 CoordinateSystem chrCS = null; 176 177 if (singleSpecies) { 178 chrCS = ssFactory.getDatabase().getChromosomeLevelCoordSystem(); 179 } else { 180 chrCS = collFactory.getDatabase().getChromosomeLevelCS(species); 181 } 182 183 if (chrCS==null || chrCS.getId()==null ) { 184 LOGGER.info("Failed to call to retrieve the CoordinateSystem for Chromosomes for: "+species.getShortName()); 185 return out; 186 } 187 188 Integer chrCSID = chrCS.getId(); 189 190 HashMap parameters = new HashMap(); 191 parameters.put("coordSysID", chrCSID); 192 193 SqlSession session = null; 194 195 try { 196 session = this.getFactory().getNewSqlSession(); 197 ChromosomeMapper mapper = session.getMapper(ChromosomeMapper.class); 198 out = mapper.getChromosomesByCoordSysID(parameters); 199 } catch (Exception e) { 200 throw new DAOException("Failed to call getChromsomes", e); 201 } finally { 202 if (session != null) { 203 session.close(); 204 } 205 } 206 for (DAChromosome c : out) { 207 c.setDaoFactory(daoFactory); 208 c.setCoordSystem(chrCS); 209 c.setSpecies(species); 210 } 211 212 return out; 213 } 214 215 @Override 216 public List<DAAssembledDNASequence> getFragments() throws DAOException { 217 218 List<DAAssembledDNASequence> out = new ArrayList<DAAssembledDNASequence>(); 219 CoordinateSystem topCS = null; 220 221 if (singleSpecies) { 222 topCS = ssFactory.getDatabase().getTopLevelCoordSystem(); 223 } else { 224 topCS = collFactory.getDatabase().getTopLevelCS(species); 225 } 226 227 if (topCS==null || topCS.getId()==null ) { 228 LOGGER.info("Failed to call to retrieve the CoordinateSystem for TopLevel for: "+species.getShortName()); 229 return out; 230 } 231 232 Integer topCSID = topCS.getId(); 233 234 HashMap parameters = new HashMap(); 235 parameters.put("coordSysID", topCSID); 236 237 SqlSession session = null; 238 239 try { 240 session = this.getFactory().getNewSqlSession(); 241 ChromosomeMapper mapper = session.getMapper(ChromosomeMapper.class); 242 out = mapper.getTopLevelFragmentsByCoordSysID(parameters); 243 } catch (Exception e) { 244 throw new DAOException("Failed to call getTopLevelFragmentsByCoordSysID", e); 245 } finally { 246 if (session != null) { 247 session.close(); 248 } 249 } 250 for (DAAssembledDNASequence c : out) { 251 c.setDaoFactory(daoFactory); 252 c.setCoordSystem(topCS); 253 c.setSpecies(species); 254 } 255 256 return out; 257 } 258 259 @Override 260 public DAChromosome getSexLinkedChromosome(Chromosome chr) throws DAOException { 261 262 263 if (chr == null || chr.getId()==null || this.getFactory()==null ) { 264 throw new DAOException("Invalid call to retrieve sex linked chromosomes"); 265 } 266 267 DAChromosome out = null; 268 269 CoordinateSystem chrCS = null; 270 271 if (singleSpecies) { 272 chrCS = ssFactory.getDatabase().getChromosomeLevelCoordSystem(); 273 } else { 274 chrCS = collFactory.getDatabase().getChromosomeLevelCS(species); 275 } 276 277 if (chrCS==null || chrCS.getId()==null ) { 278 throw new DAOException("Failed to call to retrieve the CoordinateSystem for Chromosomes"); 279 } 280 281 Integer chrCSID = chrCS.getId(); 282 283 HashMap parameters = new HashMap(); 284 parameters.put("coordSysID", chrCSID); 285 parameters.put("seqID", chr.getId()); 286 287 SqlSession session = null; 288 289 String name = null; 290 try { 291 session = this.getFactory().getNewSqlSession(); 292 ChromosomeMapper mapper = session.getMapper(ChromosomeMapper.class); 293 name = mapper.getSexLinkedChromosomeName(parameters); 294 } catch (Exception e) { 295 throw new DAOException("Failed to call getSexLinkedChromosomeChromsomes", e); 296 } finally { 297 if (session != null) { 298 session.close(); 299 } 300 } 301 302 if (name != null && !name.isEmpty()) { 303 out = this.getSpecies().getChromosomeByName(name, chr.getDBVersion()); 304 } 305 306 return out; 307 } 308 309 @Override 310 public void setAssemblyExceptions(TreeMap<String, ? extends Chromosome> chrs) throws DAOException { 311 312 TreeMap<String, DAChromosome> chromosomes = (TreeMap<String, DAChromosome>) chrs; 313 314 if (chromosomes == null || chromosomes.isEmpty() || this.getFactory()==null ) { 315 throw new DAOException("Invalid call to retrieve assembly exceptions"); 316 } 317 318 //Future proofed this to work with multi-speceies collections 319 320 Integer speciesID; 321 try { 322 DAChromosome chr1 = chromosomes.firstEntry().getValue(); 323 speciesID = this.species.getDBSpeciesID(this.getFactory().getDBVersion()); 324 if (speciesID==null) { 325 throw new Exception(); 326 } 327 } catch (Exception e) { 328 throw new DAOException("Invalid call to retrieve assembly exceptions"); 329 } 330 331 332 HashMap parameters = new HashMap(); 333 parameters.put("speciesID", speciesID); 334 335 List<HashMap> results; 336 337 SqlSession session = null; 338 339 try { 340 session = this.getFactory().getNewSqlSession(); 341 ChromosomeMapper mapper = session.getMapper(ChromosomeMapper.class); 342 results = mapper.getAssemblyExceptions(parameters); 343 } catch (Exception e) { 344 throw new DAOException("Failed to call setAssemblyExceptions", e); 345 } finally { 346 if (session != null) { 347 session.close(); 348 } 349 } 350 351 352 AssemblyExceptionRowHandler handler = null; 353 354 if (results != null && !results.isEmpty()) { 355 handler = new AssemblyExceptionRowHandler(chromosomes, results); 356 handler.handleResult(); 357 } 358 359 for (DAChromosome c:chromosomes.values()) { 360 c.setExceptions(true); 361 } 362 363 } 364 365 //as an inner class it has access to the factory etc of the enclosing class 366 public class AssemblyExceptionRowHandler implements DBResultHandler { 367 368 // the magic strings to be used as property keys for HashMap in Ibatis 369 protected final String type = "type"; 370 protected final String target = "target"; 371 protected final String target_coords = "target_coords"; 372 protected final String source_coords = "source_coords"; 373 protected final String targetCSID = "targetCSID"; 374 protected final String sourceChrName = "sourceChrName"; 375 protected final String sourceChrID = "sourceChrID"; 376 377 private TreeMap<String, DAChromosome> chromosomes = null; 378 private List<HashMap> rawResults = null; 379 380 public AssemblyExceptionRowHandler(TreeMap<String, DAChromosome> chrs , List<HashMap> results) { 381 chromosomes = chrs; 382 rawResults = results; 383 } 384 385 @Override 386 public List<DAGene> getListResult() { 387 return null; 388 } 389 390 @Override 391 public DAGene getObjectResult() { 392 return null; 393 } 394 395 public void handleResult() throws DAOException { 396 if (chromosomes ==null || chromosomes.isEmpty() 397 ||rawResults == null || rawResults.isEmpty()) { 398 return; 399 } 400 for (HashMap map : rawResults) { 401 handleRow(map); 402 } 403 } 404 405 private void handleRow(HashMap result) throws DAOException { 406 407 if (result == null || result.isEmpty()) { 408 return; 409 } 410 411 412 DAChromosome s_sequence = null; 413 DADNASequence t_sequence = null; 414 String s_name; 415 Integer s_id; 416 Coordinate s_coords = null; 417 Coordinate t_coords = null; 418 Integer t_csID = null; 419 AssemblyExceptionType ae_type = null; 420 421 422 423 s_name = (String) result.get(this.sourceChrName); 424 s_id = (Integer) result.get(this.sourceChrID); 425 426 s_sequence = this.chromosomes.get(s_name); 427 428 if (s_sequence==null || !s_sequence.getId().equals(s_id)) { 429 return; 430 } 431 432 s_coords = (Coordinate) result.get(this.source_coords); 433 434 ae_type = (AssemblyExceptionType) result.get(this.type); 435 if (ae_type == null) { 436 ae_type = AssemblyExceptionType.UNKNOWN; 437 } 438 439 t_coords = (Coordinate) result.get(this.target_coords); 440 441 if ( result.get(this.targetCSID) != null ) { 442 t_csID = (Integer) result.get(this.targetCSID); 443 } else { 444 return; 445 } 446 447 t_sequence = (DADNASequence) result.get(this.target); 448 if (t_sequence == null) { 449 return; 450 } 451 452 CoordinateSystem targetCS = null; 453 454 if (singleSpecies) { 455 targetCS = ssFactory.getDatabase().getCSByID(t_csID); 456 } else { 457 targetCS =collFactory.getDatabase().getCSByID(species, t_csID); 458 } 459 460 //we want to convert the DADNASequence to the correct type if it is an assembly! 461 462 if (targetCS.isSequenceLevel()) { 463 t_sequence.setCoordSystem(targetCS); 464 } else if (EnsemblCoordSystemType.chromosome.equals(targetCS.getType())) { 465 t_sequence = new DAChromosome((DAOCoreFactory) daoFactory); 466 t_sequence.setId(((DADNASequence) result.get(this.target)).getId()); 467 t_sequence.setName(((DADNASequence) result.get(this.target)).getName()); 468 t_sequence.setDBSeqLength(((DADNASequence) result.get(this.target)).getDBSeqLength()); 469 t_sequence.setSpecies(species); 470 t_sequence.setCoordSystem(targetCS); 471 472 //look to see if we have this sequence in cache 473 t_sequence = species.getCachedChromosome((DAChromosome) t_sequence); 474 475 } else { 476 t_sequence = new DAAssembledDNASequence((DAOCoreFactory) daoFactory); 477 t_sequence.setId(((DADNASequence) result.get(this.target)).getId()); 478 t_sequence.setName(((DADNASequence) result.get(this.target)).getName()); 479 t_sequence.setDBSeqLength(((DADNASequence) result.get(this.target)).getDBSeqLength()); 480 t_sequence.setCoordSystem(targetCS); 481 482 //look to see if we have this sequence in cache 483 t_sequence = species.getCachedFragment((DAAssembledDNASequence) t_sequence); 484 } 485 486 if (t_sequence.getDaoFactory() == null) { 487 // pgene.setType(FeatureType.gene); 488 t_sequence.setDaoFactory(daoFactory); 489 } 490 491 Mapping mapping = new Mapping(); 492 mapping.setSource(s_sequence); 493 mapping.setSourceCoordinates(s_coords); 494 mapping.setTarget(t_sequence); 495 mapping.setTargetCoordinates(t_coords); 496 497 s_sequence.addException(ae_type, mapping); 498 499 } 500 } 501 502} 503 504