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.biojava.bio.seq.db; 023 024import java.io.Serializable; 025import java.util.LinkedHashMap; 026import java.util.Iterator; 027import java.util.Map; 028import java.util.Set; 029 030import org.biojava.bio.BioException; 031import org.biojava.bio.seq.Sequence; 032import org.biojava.bio.seq.SequenceIterator; 033import org.biojava.utils.ChangeEvent; 034import org.biojava.utils.ChangeSupport; 035import org.biojava.utils.ChangeVetoException; 036 037/** 038 * An implementation of SequenceDB that uses an underlying HashMap to store the 039 * sequence objects. 040 * 041 * @author Matthew Pocock 042 * @author <A href="mailto:Gerald.Loeffler@vienna.at">Gerald Loeffler</A> 043 * @author Matias Pilpari (LinkedHashMap) 044 */ 045public class HashSequenceDB 046 extends 047 AbstractSequenceDB 048 implements 049 SequenceDB, 050 Serializable { 051 /** 052 * The sequence-by-id map. 053 */ 054 final private Map sequenceByID; 055 056 /** 057 * An object to extract an ID for a sequence. 058 */ 059 final private org.biojava.bio.seq.db.IDMaker idMaker; 060 061 /** 062 * The name of this sequence database. 063 */ 064 private String name; 065 066 public String getName() { 067 return name; 068 } 069 070 public Sequence getSequence(String id) 071 throws IllegalIDException 072 { 073 Sequence seq = (Sequence) sequenceByID.get(id); 074 if (seq == null) { 075 throw new IllegalIDException("Sequence with ID " + id + " could not be found"); 076 } 077 return seq; 078 } 079 080 public Set ids() { 081 return sequenceByID.keySet(); 082 } 083 084 public SequenceIterator sequenceIterator() { 085 return new SequenceIterator() { 086 Iterator seqI = sequenceByID.values().iterator(); 087 public boolean hasNext() { return seqI.hasNext(); } 088 public Sequence nextSequence() { return (Sequence) seqI.next(); } 089 }; 090 } 091 092 /** 093 * Add a sequence under a particular id. 094 * 095 * @param id the id to use 096 * @param seq the Sequence to add 097 * @throws ChangeVetoException if this addition was vetoed 098 */ 099 public void addSequence(String id, Sequence seq) 100 throws ChangeVetoException { 101 if(!hasListeners()) { 102 sequenceByID.put(id, seq); 103 } else { 104 ChangeSupport changeSupport = getChangeSupport(SequenceDB.SEQUENCES); 105 synchronized(changeSupport) { 106 ChangeEvent ce = new ChangeEvent( 107 this, 108 SequenceDB.SEQUENCES, 109 new Object[] { id, seq }, 110 null 111 ); 112 changeSupport.firePreChangeEvent(ce); 113 sequenceByID.put(id, seq); 114 changeSupport.firePostChangeEvent(ce); 115 } 116 } 117 } 118 119 /** 120 * Retrieve the IDMaker associated with this database. 121 * 122 * @return the current IDMaker object 123 */ 124 public org.biojava.bio.seq.db.IDMaker getIDMaker() { 125 return idMaker; 126 } 127 128 public void addSequence(Sequence seq) 129 throws ChangeVetoException { 130 String id = idMaker.calcID(seq); 131 if(!hasListeners()) { 132 addSequence(id, seq); 133 } else { 134 ChangeSupport changeSupport = getChangeSupport(SequenceDB.SEQUENCES); 135 synchronized(changeSupport) { 136 ChangeEvent ce = new ChangeEvent( 137 this, 138 SequenceDB.SEQUENCES, 139 id, 140 null 141 ); 142 changeSupport.firePreChangeEvent(ce); 143 sequenceByID.remove(id); 144 changeSupport.firePostChangeEvent(ce); 145 } 146 } 147 } 148 149 public void removeSequence(String id) 150 throws BioException, ChangeVetoException { 151 if(!hasListeners()) { 152 sequenceByID.remove(id); 153 } else { 154 ChangeSupport changeSupport = getChangeSupport(SequenceDB.SEQUENCES); 155 synchronized(changeSupport) { 156 ChangeEvent ce = new ChangeEvent( 157 this, 158 SequenceDB.SEQUENCES, 159 null, 160 id 161 ); 162 changeSupport.firePreChangeEvent(ce); 163 sequenceByID.remove(id); 164 changeSupport.firePostChangeEvent(ce); 165 } 166 } 167 } 168 169 /** 170 * Generate a HashSequenceDB object that will use byName to generate ids for 171 * sequences and have a null name. 172 */ 173 public HashSequenceDB() { 174 this(IDMaker.byName, null); 175 } 176 177 /** 178 * Generate a HashSequenceDB object that will use idMaker to generate ids for 179 * sequences and have a null name. 180 * 181 * @param idMaker the object that will work out the default id for a sequence 182 */ 183 public HashSequenceDB(org.biojava.bio.seq.db.IDMaker idMaker) { 184 this(idMaker, null); 185 } 186 187 /** 188 * Generate a HashSequenceDB object that will use byName to generate ids and 189 * will have the requested name. 190 * 191 * @param name the name for this database 192 */ 193 public HashSequenceDB(String name) { 194 this(IDMaker.byName, name); 195 } 196 197 /** 198 * Generate a HashSequenceDB object that will use idMaker to generate ids for 199 * sequences and have the requested name. 200 * 201 * @param idMaker the object that will work out the default id for a sequence 202 * @param name the name for this database 203 */ 204 public HashSequenceDB(org.biojava.bio.seq.db.IDMaker idMaker, String name) { 205 this.idMaker = idMaker; 206 this.name = name; 207 this.sequenceByID = new LinkedHashMap(); 208 } 209}