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 */
021package org.biojava.nbio.core.sequence.storage;
022
023import org.biojava.nbio.core.exceptions.CompoundNotFoundException;
024import org.biojava.nbio.core.sequence.AccessionID;
025import org.biojava.nbio.core.sequence.template.*;
026import org.biojava.nbio.core.util.Equals;
027import org.biojava.nbio.core.util.Hashcoder;
028
029import java.util.Iterator;
030import java.util.List;
031
032/**
033 * An implementation of the SequenceReader interface which for every
034 * call will return only 1 compound (given to it during construction; a String
035 * is also valid but will require a CompoundSet). The idea is to represent
036 * large runs of a single compound without the memory footprint of storing these
037 * compounds e.g. a run of 10KB of Ns in a DNASequence.
038 *
039 * @author ayates
040 */
041public class SingleCompoundSequenceReader<C extends Compound> implements ProxySequenceReader<C> {
042
043        private final C compound;
044        private final CompoundSet<C> compoundSet;
045        private final int length;
046
047        /**
048         * Public constructor to be used with String based constructor
049         */
050        public SingleCompoundSequenceReader(String compound, CompoundSet<C> compoundSet, int length) {
051                this(compoundSet.getCompoundForString(compound), compoundSet, length);
052        }
053
054        /**
055         * Build the object with a compound rather than a String
056         */
057        public SingleCompoundSequenceReader(C compound, CompoundSet<C> compoundSet, int length) {
058                this.compound = compound;
059                this.compoundSet = compoundSet;
060                this.length = length;
061        }
062
063        /**
064         * Unsupported
065         */
066
067        @Override
068        public void setCompoundSet(CompoundSet<C> compoundSet) {
069                throw new UnsupportedOperationException("Not supported.");
070        }
071
072        /**
073         * Unsupported
074         */
075
076        @Override
077        public void setContents(String sequence) throws CompoundNotFoundException {
078                throw new UnsupportedOperationException("Not supported.");
079        }
080
081        /**
082         * Returns the length given during construction
083         */
084
085        @Override
086        public int getLength() {
087                return length;
088        }
089
090        /**
091         * Always returns the compound given at construction
092         */
093
094        @Override
095        public C getCompoundAt(int position) {
096                return compound;
097        }
098
099        /**
100         * Returns 1 if the given compound is equal to the one given during
101         * construction; otherwise will return -1.
102         */
103
104        @Override
105        public int getIndexOf(C compound) {
106                if(compound.equals(this.compound)) {
107                        return 1;
108                }
109                return -1;
110        }
111
112        /**
113         * Returns the length of the Sequence if the given compound was equal to
114         * the one given during construction. Otherwise returns -1
115         */
116
117        @Override
118        public int getLastIndexOf(C compound) {
119                if(compound.equals(this.compound)) {
120                        return getLength();
121                }
122                return -1;
123        }
124
125        /**
126         * Delegates to {@link SequenceMixin#toList(org.biojava.nbio.core.sequence.template.Sequence) }
127         */
128
129        @Override
130        public String getSequenceAsString() {
131                return SequenceMixin.toString(this);
132        }
133
134        /**
135         * Delegates to {@link SequenceMixin#toList(org.biojava.nbio.core.sequence.template.Sequence) }
136         */
137
138        @Override
139        public List<C> getAsList() {
140                return SequenceMixin.toList(this);
141        }
142
143        /**
144         * Creates a {@link SequenceProxyView} for the given coordinates
145         */
146
147        @Override
148        public SequenceView<C> getSubSequence(Integer start, Integer end) {
149                return new SequenceProxyView<C>(this, start, end);
150        }
151
152        /**
153         * Returns the compound set given at construction
154         */
155
156        @Override
157        public CompoundSet<C> getCompoundSet() {
158                return compoundSet;
159        }
160
161        /**
162         * Unsupoorted
163         */
164
165        @Override
166        public AccessionID getAccession() {
167                throw new UnsupportedOperationException("Not supported yet.");
168        }
169
170        /**
171         * Delegates to {@link SequenceMixin#countCompounds(org.biojava.nbio.core.sequence.template.Sequence, C[]) }
172         */
173
174        @Override
175        public int countCompounds(C... compounds) {
176                return SequenceMixin.countCompounds(this, compounds);
177        }
178
179        /**
180         * Returns an instance of {@link SequenceMixin.SequenceIterator}
181         */
182
183        @Override
184        public Iterator<C> iterator() {
185                return new SequenceMixin.SequenceIterator<C>(this);
186        }
187
188        @Override
189        public SequenceView<C> getInverse() {
190                return SequenceMixin.inverse(this);
191        }
192
193        @Override
194        public int hashCode() {
195                int s = Hashcoder.SEED;
196                s = Hashcoder.hash(s, compound);
197                s = Hashcoder.hash(s, length);
198                s = Hashcoder.hash(s, compoundSet);
199                return s;
200        }
201
202        @Override
203        @SuppressWarnings("unchecked")
204        public boolean equals(Object o) {
205                if(Equals.classEqual(this, o)) {
206                        SingleCompoundSequenceReader<C> that = (SingleCompoundSequenceReader<C>)o;
207                        return  Equals.equal(compound, that.compound) &&
208                                        Equals.equal(compoundSet, that.compoundSet) &&
209                                        Equals.equal(length, that.length);
210                }
211                return false;
212        }
213
214        public boolean equals(Sequence<C> o) {
215                if(Equals.classEqual(this, o)) {
216                        SingleCompoundSequenceReader<C> that = (SingleCompoundSequenceReader<C>)o;
217                        return  Equals.equal(compound, that.compound) &&
218                                        Equals.equal(compoundSet, that.compoundSet) &&
219                                        Equals.equal(length, that.length);
220                }
221                return false;
222        }
223}