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 * Created on 01-21-2010
021 *
022 * @author Richard Holland
023 *
024 *
025 */
026package org.biojava.nbio.core.sequence.template;
027
028import org.biojava.nbio.core.sequence.AccessionID;
029
030import java.util.Iterator;
031import java.util.List;
032
033public class SequenceProxyView<C extends Compound> implements SequenceView<C> {
034
035        private Integer bioStart;
036        private Integer bioEnd;
037        private Sequence<C> sequence;
038
039        public SequenceProxyView() {
040        }
041
042        public SequenceProxyView(Sequence<C> sequence) {
043                this(sequence, 1, sequence.getLength());
044        }
045
046        /**
047         * Main constructor for working with SequenceProxyViews
048         *
049         * @param sequence Sequence to proxy
050         * @param bioStart Start; cannot be less than 1
051         * @param bioEnd End; cannot be greater than the sequence length
052         */
053        public SequenceProxyView(Sequence<C> sequence, Integer bioStart, Integer bioEnd) {
054                this.sequence = sequence;
055                setBioStart(bioStart);
056                setBioEnd(bioEnd);
057        }
058
059        @Override
060        public Sequence<C> getViewedSequence() {
061                return sequence;
062        }
063
064        @Override
065        public String getSequenceAsString() {
066                return SequenceMixin.toString(this);
067        }
068
069        @Override
070        public List<C> getAsList() {
071                return SequenceMixin.toList(this);
072        }
073
074        @Override
075        public C getCompoundAt(int position) {
076                return getViewedSequence().getCompoundAt((getBioStart() + position) - 1);
077        }
078
079        @Override
080        public int getIndexOf(C compound) {
081                return SequenceMixin.indexOf(this, compound);
082        }
083
084        @Override
085        public int getLastIndexOf(C compound) {
086                return SequenceMixin.lastIndexOf(this, compound);
087        }
088
089        @Override
090        public int getLength() {
091                return (getBioEnd() - getBioStart()) + 1;
092        }
093
094        @Override
095        public CompoundSet<C> getCompoundSet() {
096                return getViewedSequence().getCompoundSet();
097        }
098
099        @Override
100        public SequenceView<C> getSubSequence(final Integer bioStart, final Integer bioEnd) {
101                return new SequenceProxyView<C>(this, bioStart, bioEnd);
102        }
103
104        @Override
105        public Iterator<C> iterator() {
106                return new SequenceMixin.SequenceIterator<C>(this);
107        }
108
109        @Override
110        public AccessionID getAccession() {
111                return getViewedSequence().getAccession();
112        }
113
114        /**
115         * @return the bioStart
116         */
117        @Override
118        public Integer getBioStart() {
119                return bioStart;
120        }
121
122        /**
123         * @param bioStart the bioStart to set
124         */
125        public void setBioStart(Integer bioStart) {
126                if (bioStart < 1) {
127                        throw new IllegalArgumentException("The given start "
128                                        + bioStart + " is less than 1; cannot index less than 1");
129                }
130                this.bioStart = bioStart;
131        }
132
133        /**
134         * @return the bioEnd
135         */
136        @Override
137        public Integer getBioEnd() {
138                return bioEnd;
139        }
140
141        /**
142         * @param bioEnd the bioEnd to set
143         */
144        public void setBioEnd(Integer bioEnd) {
145                if(sequence == null) {
146                        throw new NullPointerException("No sequence given before setting the end coordinate; cannot be done");
147                }
148                // had a bug in the code that allowed this to work. The length of a any exon or cds sequence was always the length of the
149                //parent sequence. Sequence class doesn't have bioStart and bioEnd exposed to do a proper comparison of getting
150                // a subsequence. Januar-20=2011 Scooter
151         //   if (bioEnd > sequence.getLength()) {
152         //       throw new IllegalArgumentException("The given end "
153         //               + bioEnd + " is greater than sequence length"
154         //               + sequence.getLength());
155         //   }
156                this.bioEnd = bioEnd;
157        }
158
159        @Override
160        public int countCompounds(C... compounds) {
161                return SequenceMixin.countCompounds(this, compounds);
162        }
163
164        @Override
165        public SequenceView<C> getInverse() {
166                return SequenceMixin.inverse(this);
167        }
168}