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;
023import java.util.HashMap;
024import java.util.Iterator;
025import java.util.Map;
026import java.util.Set;
027
028import org.biojava.bio.BioException;
029import org.biojava.bio.seq.db.IllegalIDException;
030import org.biojava.utils.ChangeEvent;
031import org.biojava.utils.ChangeSupport;
032import org.biojava.utils.ChangeVetoException;
033import org.biojavax.bio.BioEntry;
034
035
036/**
037 * An implementation of RichSequenceDB that uses an underlying HashMap to store the
038 * RichSequence objects.
039 *
040 * @author Matthew Pocock
041 * @author Gerald Loeffler
042 * @author Richard Holland
043 * @since 1.5
044 */
045public class HashBioEntryDB extends AbstractBioEntryDB implements BioEntryDB {
046    
047    /**
048     * The sequence-by-id map.
049     */
050    final private Map sequenceByID;
051        
052    /**
053     * The name of this sequence database.
054     */
055    private String name;
056    
057    /**
058     * Generate a HashRichSequenceDB object that will use byName to generate ids for
059     * sequences and have a null name.
060     */
061    public HashBioEntryDB() {
062        this(null);
063    }
064    
065    /**
066     * Generate a HashRichSequenceDB object that will use byName to generate ids and
067     * will have the requested name.
068     *
069     * @param name the name for this database
070     */
071    public HashBioEntryDB(String name) {
072        this.name = name;
073        this.sequenceByID = new HashMap();
074    }
075    
076    public String getName() {
077        return name;
078    }
079    
080    public BioEntry getBioEntry(String id) throws BioException, IllegalIDException {
081        BioEntry seq = (BioEntry)sequenceByID.get(id);
082        if (seq == null) throw new IllegalIDException("BioEntry with ID " + id + " could not be found");
083        return seq;
084    }
085    
086    public BioEntryDB getBioEntrys(Set ids) throws BioException, IllegalIDException {
087        return this.getBioEntrys(ids,null);
088    }
089    
090    public BioEntryDB getBioEntrys(Set ids, BioEntryDB db) throws BioException, IllegalIDException {
091        if (db==null) db = new HashBioEntryDB();
092        for (Iterator i = ids.iterator(); i.hasNext(); ) {
093            String id = (String)i.next();
094            if (!sequenceByID.containsKey(id)) throw new IllegalIDException("BioEntry with ID " + id + " could not be found");
095            else {
096                try {
097                    db.addBioEntry((BioEntry)sequenceByID.get(id));
098                } catch (ChangeVetoException ce) {
099                    throw new BioException("Unexpectedly couldn't add to a HashBioEntryDB", ce);
100                }
101            }
102        }
103        return db;
104    }
105    
106    public Set ids() {
107        return sequenceByID.keySet();
108    }
109    
110    /**
111     * Add a BioEntry, the name of the BioEntry will be used as the ID
112     * @param seq the BioEntry to add
113     * @throws ChangeVetoException if this addition was vetoed
114     */
115    public void addBioEntry(BioEntry seq) throws IllegalIDException, BioException, ChangeVetoException {
116        this.addBioEntry(seq.getName(), seq);
117    }
118    
119    protected void addBioEntry(String id, BioEntry seq) throws IllegalIDException, BioException, ChangeVetoException {
120        if(!hasListeners(BioEntryDB.BIOENTRYS)) {
121            sequenceByID.put(id, seq);
122        } else {
123            ChangeSupport changeSupport = getChangeSupport(BioEntryDB.BIOENTRYS);
124            synchronized(changeSupport) {
125                ChangeEvent ce = new ChangeEvent(
126                        this,
127                        BioEntryDB.BIOENTRYS,
128                        new Object[] { id, seq },
129                        null);
130                        changeSupport.firePreChangeEvent(ce);
131                        sequenceByID.put(id, seq);
132                        changeSupport.firePostChangeEvent(ce);
133            }
134        }
135    }
136    
137    public void removeBioEntry(String id) throws IllegalIDException, BioException, ChangeVetoException {
138        if (!sequenceByID.containsKey(id)) throw new IllegalIDException("BioEntry with ID " + id + " could not be found");
139        if(!hasListeners(BioEntryDB.BIOENTRYS)) {
140            sequenceByID.remove(id);
141        } else {
142            ChangeSupport changeSupport = getChangeSupport(BioEntryDB.BIOENTRYS);
143            synchronized(changeSupport) {
144                ChangeEvent ce = new ChangeEvent(
145                        this,
146                        BioEntryDB.BIOENTRYS,
147                        null,
148                        id
149                        );
150                changeSupport.firePreChangeEvent(ce);
151                sequenceByID.remove(id);
152                changeSupport.firePostChangeEvent(ce);
153            }
154        }
155    }
156}