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.Set;
026
027import org.biojava.bio.BioException;
028import org.biojava.bio.seq.Sequence;
029import org.biojava.bio.seq.SequenceAnnotator;
030import org.biojava.bio.seq.SequenceIterator;
031import org.biojava.bio.symbol.IllegalAlphabetException;
032import org.biojava.utils.ChangeVetoException;
033
034/**
035 * SequenceDB implementation which lazily applies a SequenceAnnotator
036 * to sequences retrieved from a SequenceDB.
037 *
038 * @author Thomas Down
039 * @author Matthew Pocock
040 */
041
042public class AnnotatedSequenceDB
043extends AbstractSequenceDB
044implements SequenceDB, Serializable {
045  private final SequenceDB parent;
046  private final SequenceAnnotator annotator;
047
048  public AnnotatedSequenceDB(SequenceDB parent, SequenceAnnotator a) {
049    this.parent = parent;
050    this.annotator = a;
051  }
052
053   /**
054    * Get the original sequenceDB from this annotated sequenceDB.
055    */
056
057  public SequenceDB getParent() {
058    return this.parent;
059  }
060
061  public String getName() {
062    return parent.getName() + " (" + annotator.toString() + ")";
063  }
064
065  public Sequence getSequence(String id)
066  throws BioException {
067    return doAnnotation(parent.getSequence(id));
068  }
069
070  public Set ids() {
071    return parent.ids();
072  }
073
074  public SequenceIterator sequenceIterator() {
075    return new SequenceIterator() {
076      SequenceIterator pi = parent.sequenceIterator();
077
078            public boolean hasNext() {
079        return pi.hasNext();
080            }
081
082            public Sequence nextSequence() throws BioException {
083        return doAnnotation(pi.nextSequence());
084            }
085    };
086  }
087
088   /**
089    * Apply the annotation to a sequence.
090    * @param seq the sequence to annotate.
091    */
092
093  protected Sequence doAnnotation(Sequence seq) throws BioException  {
094    try {
095      return annotator.annotate(seq);
096    } catch (IllegalAlphabetException ex) {
097      throw new BioException("Couldn't apply annotator " + annotator.toString() + " to " + seq.getURN(), ex);
098    } catch (ChangeVetoException cve) {
099      throw new BioException("Couldn't apply annotator " + annotator.toString() + " to " + seq.getURN(), cve);
100    }
101  }
102}