package org.seqcode.genome; import java.util.*; import java.sql.*; import org.seqcode.data.connections.DatabaseConnectionManager; import org.seqcode.data.connections.DatabaseException; import org.seqcode.data.connections.DatabaseSequence; import org.seqcode.data.connections.UnknownRoleException; import org.seqcode.gseutils.*; /** * Species represents a species in our database */ public class Species{ //static cache of all Species private static Map<String,Species> organisms = new HashMap<String,Species>(); private static Map<Integer, Species> organismsids = new HashMap<Integer,Species>(); //Variables that define this Species private String species; private int dbid; /** * Constructor: no db lookup needed * @param id : use -1 for fake organisms (i.e. not in db) * @param species * @throws NotFoundException */ public Species(int id, String species){ this.dbid = id; this.species = species; } /** * Constructor: look up species name in core database * @param species * @throws NotFoundException */ public Species(String species) throws NotFoundException { this.species = species; if(organisms.isEmpty()){ getAllSpecies(false); } if (organisms.containsKey(species)) { this.dbid = organisms.get(species).getDBID(); }else{ //Try looking up in the database, in case it was put there since organismids was populated Connection cxn = null; Statement stmt = null; ResultSet rs = null; try { cxn = DatabaseConnectionManager.getConnection("core"); stmt = cxn.createStatement(); rs = stmt.executeQuery("select id from species where name = '" + species + "'"); if (rs.next()) { this.dbid = rs.getInt(1); } else { throw new NotFoundException("Couldn't find " + species); } } catch (SQLException ex) { ex.printStackTrace(); throw new DatabaseException("Couldn't find " + species + ": " + ex.toString(), ex); } catch (UnknownRoleException ex) { ex.printStackTrace(); throw new DatabaseException("Couldn't connect with role core", ex); } finally { if (rs != null) { try {rs.close(); } catch (SQLException ex) { }} if (stmt != null) { try { stmt.close();} catch (SQLException ex) { } } if (cxn!=null) try {cxn.close();}catch (Exception ex) {throw new DatabaseException("Couldn't close connection with role core", ex); } } } } /** * Constructor: look up dbid in core database * @param speciesID * @throws NotFoundException */ public Species(int speciesID) throws NotFoundException { this.dbid = speciesID; if(organisms.isEmpty()){ getAllSpecies(false); } if (organisms.containsKey(dbid)) { this.species = organisms.get(dbid).getName(); }else{ //Try looking up in the database, in case it was put there since organismids was populated java.sql.Connection cxn = null; Statement stmt = null; ResultSet rs = null; try { cxn = DatabaseConnectionManager.getConnection("core"); stmt = cxn.createStatement(); rs = stmt.executeQuery("select name from species where id=" + dbid); if (rs.next()) { species = rs.getString(1); } else { throw new NotFoundException("Couldn't find " + dbid); } } catch (SQLException ex) { throw new DatabaseException("Couldn't find " + dbid + ": " + ex.toString(), ex); } catch (UnknownRoleException ex) { throw new DatabaseException("Couldn't connect with role core", ex); } finally { if (rs != null) { try {rs.close(); } catch (SQLException ex) { }} if (stmt != null) { try { stmt.close();} catch (SQLException ex) { } } if(cxn!=null) try {cxn.close();}catch (Exception ex) {throw new DatabaseException("Couldn't close connection with role core", ex); } } } } /** * Accessor for species name */ public String getName() { return species; } /** * Accessor for database ID */ public int getDBID() { return dbid; } /** * Returns a list of genomes for this species * @return */ public Collection<Genome> getGenomes(){ try { return Genome.getAllGenomesBySpecies(this); } catch (NotFoundException e) { e.printStackTrace(); } return null; } /** * Returns a list of genome names for this species * @return */ public Collection<String> getGenomeNames(){ List<String> names = new ArrayList<String>(); for(Genome g : getGenomes()){ names.add(g.getVersion()); } return names; } /** * Load all Organisms from database * @return */ public static Collection<Species> getAllSpecies(boolean forceRefreshFromDB){ List<Species> orgs = new ArrayList<Species>(); if(organisms.isEmpty() || forceRefreshFromDB){ organisms.clear(); organismsids.clear(); Connection cxn = null; Statement stmt = null; ResultSet rs = null; try { cxn = DatabaseConnectionManager.getConnection("core"); stmt = cxn.createStatement(); rs = stmt.executeQuery("select id, name from species"); while(rs.next()) { Species org = new Species(rs.getInt(1), rs.getString(2)); orgs.add(org); organisms.put(org.getName(), org); organismsids.put(org.getDBID(), org); } } catch (SQLException ex) { ex.printStackTrace(); throw new DatabaseException("mySQL error: " + ex.toString(), ex); } catch (UnknownRoleException ex) { ex.printStackTrace(); throw new DatabaseException("Couldn't connect with role core", ex); } finally { if (rs != null) { try {rs.close(); } catch (SQLException ex) { ex.printStackTrace(); }} if (stmt != null) { try { stmt.close();} catch (SQLException ex) {ex.printStackTrace();} } if (cxn!=null) try {cxn.close();}catch (Exception ex) {ex.printStackTrace();} } }else{ orgs.addAll(organisms.values()); } return orgs; } /** * Get a specific Species by name * @param species * @return * @throws NotFoundException */ public static Species getSpecies(String species) throws NotFoundException { if(organisms.isEmpty()){ getAllSpecies(false); } if (organisms.containsKey(species)) { return organisms.get(species); } else { Species o = new Species(species); organisms.put(species, o); organismsids.put(o.getDBID(), o); return o; } } /** * Get a specific Species by ID * @param species * @return * @throws NotFoundException */ public static Species getSpecies(int species) throws NotFoundException { if(organisms.isEmpty()){ getAllSpecies(false); } if (organismsids.containsKey(species)) { return organismsids.get(species); } else { Species o = new Species(species); organisms.put(o.getName(), o); organismsids.put(o.getDBID(), o); return o; } } /** * Get all Species names from the database * @return */ public static Collection<String> getAllSpeciesNames(boolean forceRefreshFromDB) { if(organisms.isEmpty() || forceRefreshFromDB){ getAllSpecies(forceRefreshFromDB); } return organisms.keySet(); } /** * Insert a new Species into the database * @param species * @throws SQLException */ public static void insertSpecies(String species) throws SQLException { java.sql.Connection cxn = null; Statement stmt = null; try { cxn = DatabaseConnectionManager.getConnection("core"); stmt = cxn.createStatement(); String nextIdString = DatabaseSequence.getInsertSQL(cxn, "species_id"); String sql = String.format("insert into species values (%s, '%s')", nextIdString, species); System.out.println(sql); stmt.executeUpdate(sql); Species o = new Species(new Integer(nextIdString), species); organisms.put(species, o); organismsids.put(o.getDBID(), o); } catch (UnknownRoleException ex) { throw new DatabaseException("Couldn't connect with role core", ex); } catch (SQLException se) { throw se; } finally { if (stmt != null) { try { stmt.close();} catch (SQLException ex) { } } if(cxn!=null) try {cxn.close();}catch (Exception ex) {throw new DatabaseException("Couldn't close connection with role core", ex); } } } }