001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021 022package org.biojavax.bio.db.biosql; 023import java.lang.reflect.Method; 024import java.util.HashSet; 025import java.util.Iterator; 026import java.util.List; 027import java.util.Set; 028 029import org.biojava.bio.BioException; 030import org.biojava.bio.seq.db.IllegalIDException; 031import org.biojava.utils.ChangeEvent; 032import org.biojava.utils.ChangeSupport; 033import org.biojava.utils.ChangeVetoException; 034import org.biojavax.bio.BioEntry; 035import org.biojavax.bio.db.AbstractBioEntryDB; 036import org.biojavax.bio.db.BioEntryDB; 037import org.biojavax.bio.db.BioEntryDBLite; 038import org.biojavax.bio.db.HashBioEntryDB; 039 040 041/** 042 * 043 * @author Richard Holland 044 * @author David Scott 045 * @since 1.5 046 */ 047public class BioSQLBioEntryDB extends AbstractBioEntryDB { 048 049 private Object session; 050 private String name; 051 052 private Method createQuery; 053 private Method setParameter; 054 private Method list; 055 private Method delete; 056 private Method saveOrUpdate; 057 058 /** Creates a new instance of BioSQLBioEntryDB */ 059 public BioSQLBioEntryDB(Object session) { 060 this(null,session); 061 } 062 063 /** Creates a new instance of BioSQLBioEntryDB */ 064 public BioSQLBioEntryDB(String name, Object session) { 065 this.name = name; 066 this.session = session; 067 try { 068 // Lazy load the Session class from Hibernate. 069 Class hibernateSession = session.getClass(); 070 Class realHibernateSession = Class.forName("org.hibernate.Session"); 071 // Test to see if our parameter is really a Session 072 if (!realHibernateSession.isAssignableFrom(hibernateSession)) 073 throw new IllegalArgumentException("Parameter must be a org.hibernate.Session object"); 074 this.session = session; 075 // Lookup the createQuery method 076 this.createQuery = hibernateSession.getMethod("createQuery", new Class[]{String.class}); 077 this.delete = hibernateSession.getMethod("delete", new Class[]{String.class,Object.class}); 078 this.saveOrUpdate = hibernateSession.getMethod("saveOrUpdate", new Class[]{String.class,Object.class}); 079 // Lazy load the Query class from Hibernate. 080 Class hibernateQuery = Class.forName("org.hibernate.Query"); 081 // Lookup the setParameter and uniqueQuery methods 082 this.setParameter = hibernateQuery.getMethod("setParameter", new Class[]{int.class,Object.class}); 083 this.list = hibernateQuery.getMethod("list", new Class[]{}); 084 } catch (ClassNotFoundException e) { 085 throw new RuntimeException(e); 086 } catch (NoSuchMethodException e) { 087 throw new RuntimeException(e); 088 } 089 } 090 091 public String getName() { 092 return this.name; 093 } 094 095 public Object getHibernateSession() { 096 return this.session; 097 } 098 099 public Set ids() { 100 try { 101 // Build the query object 102 String queryText = "select distinct name from BioEntry"; 103 Object query = this.createQuery.invoke(this.session, new Object[]{queryText}); 104 // Get the results 105 List result = (List)this.list.invoke(query, (Object[])null); 106 // Return the found object, if found - null if not. 107 return new HashSet(result); 108 } catch (Exception e) { 109 // Throw the exception with our nice message 110 throw new RuntimeException("Error while trying to load all names",e); 111 } 112 } 113 114 public BioEntry getBioEntry(String id) throws IllegalIDException, BioException { 115 try { 116 // Build the query object 117 String queryText = "from BioEntry where name = ?"; 118 Object query = this.createQuery.invoke(this.session, new Object[]{queryText}); 119 // Set the parameters 120 query = this.setParameter.invoke(query, new Object[]{new Integer(0), id}); 121 // Get the results 122 List result = (List)this.list.invoke(query, (Object[])null); 123 // If the result doesn't just have a single entry, throw an exception 124 if (result.size()==0) throw new IllegalIDException("Id not found: "+id); 125 else if (result.size()>1) throw new IllegalIDException("Multiple records found with that id - use getBioEntrys: "+id); 126 // Return the found object, if found - null if not. 127 return (BioEntry)result.get(0); 128 } catch (Exception e) { 129 // Throw the exception with our nice message 130 throw new RuntimeException("Error while trying to load by id: "+id,e); 131 } 132 } 133 134 public BioEntryDB getBioEntrys(Set ids) throws BioException, IllegalIDException { 135 return this.getBioEntrys(ids,null); 136 } 137 138 public BioEntryDB getBioEntrys(Set ids, BioEntryDB db) throws BioException, IllegalIDException { 139 if (db==null) db = new HashBioEntryDB(); 140 try { 141 for (Iterator i = ids.iterator(); i.hasNext(); ) { 142 String id = (String)i.next(); 143 // Build the query object 144 String queryText = "from BioEntry where name = ?"; 145 Object query = this.createQuery.invoke(this.session, new Object[]{queryText}); 146 // Set the parameters 147 query = this.setParameter.invoke(query, new Object[]{new Integer(0), id}); 148 // Get the results 149 List result = (List)this.list.invoke(query, (Object[])null); 150 // If the result doesn't just have a single entry, throw an exception 151 if (result.size()==0) throw new IllegalIDException("Id not found: "+id); 152 // Add the results to the results db. 153 for (Iterator j = result.iterator(); j.hasNext(); ) db.addBioEntry((BioEntry)j.next()); 154 } 155 } catch (Exception e) { 156 // Throw the exception with our nice message 157 throw new RuntimeException("Error while trying to load by ids: "+ids,e); 158 } 159 return db; 160 } 161 162 public void removeBioEntry(String id) throws IllegalIDException, BioException, ChangeVetoException { 163 if(!hasListeners(BioEntryDBLite.BIOENTRYS)) { 164 this._removeBioEntry(id); 165 } else { 166 ChangeSupport changeSupport = getChangeSupport(BioEntryDBLite.BIOENTRYS); 167 synchronized(changeSupport) { 168 ChangeEvent ce = new ChangeEvent( 169 this, 170 BioEntryDBLite.BIOENTRYS, 171 null, 172 id 173 ); 174 changeSupport.firePreChangeEvent(ce); 175 this._removeBioEntry(id); 176 changeSupport.firePostChangeEvent(ce); 177 } 178 } 179 } 180 181 private void _removeBioEntry(String id) throws IllegalIDException, BioException, ChangeVetoException { 182 try { 183 // Find the object 184 BioEntry be = this.getBioEntry(id); 185 // Get the results 186 this.delete.invoke(this.session, new Object[]{"BioEntry",be}); 187 } catch (Exception e) { 188 // Throw the exception with our nice message 189 throw new RuntimeException("Error while trying to delete by id: "+id,e); 190 } 191 } 192 193 public void addBioEntry(BioEntry seq) throws IllegalIDException, BioException, ChangeVetoException { 194 if(!hasListeners(BioEntryDBLite.BIOENTRYS)) { 195 this._addBioEntry(seq); 196 } else { 197 ChangeSupport changeSupport = getChangeSupport(BioEntryDBLite.BIOENTRYS); 198 synchronized(changeSupport) { 199 ChangeEvent ce = new ChangeEvent( 200 this, 201 BioEntryDBLite.BIOENTRYS, 202 null, 203 seq 204 ); 205 changeSupport.firePreChangeEvent(ce); 206 this._addBioEntry(seq); 207 changeSupport.firePostChangeEvent(ce); 208 } 209 } 210 } 211 212 public void _addBioEntry(BioEntry seq) throws IllegalIDException, BioException, ChangeVetoException { 213 try { 214 // Get the results 215 this.saveOrUpdate.invoke(this.session, new Object[]{"BioEntry",seq}); 216 } catch (Exception e) { 217 // Throw the exception with our nice message 218 throw new RuntimeException("Error while trying to save BioEntry with id: "+seq.getName(),e); 219 } 220 } 221 222}