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.impl;
023
024import org.biojava.bio.BioError;
025import org.biojava.bio.seq.DNATools;
026import org.biojava.bio.seq.Feature;
027import org.biojava.bio.seq.FeatureHolder;
028import org.biojava.bio.seq.Sequence;
029import org.biojava.bio.seq.StrandedFeature;
030import org.biojava.bio.symbol.IllegalAlphabetException;
031import org.biojava.bio.symbol.SymbolList;
032import org.biojava.utils.ChangeEvent;
033import org.biojava.utils.ChangeSupport;
034import org.biojava.utils.ChangeVetoException;
035
036/**
037 * A no-frills implementation of StrandedFeature.
038 *
039 * @author Matthew Pocock
040 * @author Thomas Down
041 */
042public class SimpleStrandedFeature extends SimpleFeature implements StrandedFeature {
043    private StrandedFeature.Strand strand;
044
045    public StrandedFeature.Strand getStrand() {
046        return strand;
047    }
048
049    public SymbolList getSymbols() {
050        SymbolList symList = super.getSymbols();
051        if (getStrand() == NEGATIVE) {
052            try {
053                symList = DNATools.reverseComplement(symList);
054            } catch (IllegalAlphabetException iae) {
055                throw new BioError(
056                                       "Could not retrieve symbols for feature as " +
057                                       "the alphabet can not be complemented.", iae
058                                       );
059            }
060        }
061        return symList;
062    }
063
064    public void setStrand(Strand strand)
065        throws ChangeVetoException {
066        if (hasListeners()) {
067            ChangeSupport cs = getChangeSupport(STRAND);
068            synchronized(cs) {
069                ChangeEvent ce =
070                    new ChangeEvent(this, STRAND, strand, this.strand);
071                cs.firePreChangeEvent(ce);
072                this.strand = strand;
073                cs.firePostChangeEvent(ce);
074            }
075        } else {
076            this.strand = strand;
077        }
078    }
079
080  public Feature.Template makeTemplate() {
081    StrandedFeature.Template ft = new StrandedFeature.Template();
082    fillTemplate(ft);
083    return ft;
084  }
085
086  protected void fillTemplate(StrandedFeature.Template ft) {
087    super.fillTemplate(ft);
088    ft.strand = getStrand();
089  }
090
091    public SimpleStrandedFeature(Sequence sourceSeq,
092                                 FeatureHolder parent,
093                                 StrandedFeature.Template template)
094        throws IllegalArgumentException
095               //, IllegalAlphabetException
096    {
097        super(sourceSeq, parent, template);
098        this.strand = template.strand;
099        if (sourceSeq.getAlphabet() != DNATools.getDNA()) {
100            // throw new IllegalAlphabetException (
101            // "Can not create a stranded feature within a sequence of type " +
102            //                  sourceSeq.getAlphabet().getName()
103            //                                  );
104        }
105    }
106
107    public String toString() {
108        String pm;
109        if(getStrand() == POSITIVE) {
110            pm = "+";
111        } else {
112            pm = "-";
113        }
114        return super.toString() + " " + pm;
115    }
116}