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     */
026    package org.biojava3.core.sequence.storage;
027    
028    import java.util.ArrayList;
029    import java.util.Iterator;
030    import java.util.List;
031    import org.biojava3.core.sequence.AccessionID;
032    
033    import org.biojava3.core.sequence.template.SequenceProxyView;
034    import org.biojava3.core.sequence.template.Compound;
035    import org.biojava3.core.exceptions.CompoundNotFoundError;
036    import org.biojava3.core.sequence.Strand;
037    
038    import org.biojava3.core.sequence.template.CompoundSet;
039    import org.biojava3.core.sequence.template.SequenceMixin;
040    import org.biojava3.core.sequence.template.SequenceReader;
041    import org.biojava3.core.sequence.template.SequenceView;
042    
043    /**
044     * Stores a Sequence as a collection of compounds in an ArrayList
045     *
046     * @param <C>
047     */
048    public class ArrayListSequenceReader<C extends Compound> implements SequenceReader<C> {
049    
050        private CompoundSet<C> compoundSet;
051        private List<C> parsedCompounds = new ArrayList<C>();
052    /**
053     *
054     */
055        public ArrayListSequenceReader() {
056            //Do nothing
057        }
058    /**
059     *
060     * @param compounds
061     * @param compoundSet
062     */
063        public ArrayListSequenceReader(List<C> compounds, CompoundSet<C> compoundSet) {
064            setCompoundSet(compoundSet);
065            setContents(compounds);
066        }
067    /**
068     *
069     * @param sequence
070     * @param compoundSet
071     */
072        public ArrayListSequenceReader(String sequence, CompoundSet<C> compoundSet) {
073            setCompoundSet(compoundSet);
074            setContents(sequence);
075        }
076    
077    /**
078     *
079     * @return
080     */
081        public String getSequenceAsString() {
082            return getSequenceAsString(1, getLength(), Strand.POSITIVE);
083        }
084    
085    /**
086     * 
087     * @param begin
088     * @param end
089     * @param strand
090     * @return
091     */
092    
093        public String getSequenceAsString(Integer begin, Integer end, Strand strand) {
094            // TODO Optimise/cache.
095            SequenceAsStringHelper<C> sequenceAsStringHelper = new SequenceAsStringHelper<C>();
096            return sequenceAsStringHelper.getSequenceAsString(this.parsedCompounds, compoundSet, begin, end, strand);
097        }
098    /**
099     *
100     * @return
101     */
102        
103        public List<C> getAsList() {
104            return this.parsedCompounds;
105        }
106    
107     /**
108      *
109      * @param position
110      * @return
111      */
112        public C getCompoundAt(int position) {
113            return this.parsedCompounds.get(position - 1);
114        }
115    
116     /**
117      *
118      * @param compound
119      * @return
120      */
121        public int getIndexOf(C compound) {
122            return this.parsedCompounds.indexOf(compound) + 1;
123        }
124    /**
125     *
126     * @param compound
127     * @return
128     */
129        
130        public int getLastIndexOf(C compound) {
131            return this.parsedCompounds.lastIndexOf(compound) + 1;
132        }
133    /**
134     *
135     * @return
136     */
137        
138        public int getLength() {
139            return this.parsedCompounds.size();
140        }
141    /**
142     *
143     * @return
144     */
145        
146        public Iterator<C> iterator() {
147            return this.parsedCompounds.iterator();
148        }
149    /**
150     *
151     * @param compoundSet
152     */
153        
154        public void setCompoundSet(CompoundSet<C> compoundSet) {
155            this.compoundSet = compoundSet;
156        }
157    /**
158     *
159     * @return
160     */
161        
162        public CompoundSet<C> getCompoundSet() {
163            return compoundSet;
164        }
165    /**
166     *
167     * @param sequence
168     */
169        
170        public void setContents(String sequence) {
171            // Horrendously inefficient - pretty much the way the old BJ did things.
172            // TODO Should be optimised.
173            this.parsedCompounds.clear();
174            int maxCompoundLength = compoundSet.getMaxSingleCompoundStringLength();
175            int length = sequence.length();
176            for (int i = 0; i < length;) {
177                String compoundStr = null;
178                C compound = null;
179                for (int compoundStrLength = 1; compound == null && compoundStrLength <= maxCompoundLength; compoundStrLength++) {
180                    compoundStr = sequence.substring(i, i + compoundStrLength);
181                    compound = compoundSet.getCompoundForString(compoundStr);
182                }
183                if (compound == null) {
184                    throw new CompoundNotFoundError("Cannot find compound for: "+compoundStr);
185                } else {
186                    i += compoundStr.length();
187                }
188                this.parsedCompounds.add(compound);
189            }
190        }
191    /**
192     *
193     * @param list
194     */
195        public void setContents(List<C> list) {
196            parsedCompounds.clear();
197            for (C c : list) {
198                parsedCompounds.add(c);
199            }
200        }
201    /**
202     *
203     * @param bioBegin
204     * @param bioEnd
205     * @return
206     */
207        
208        public SequenceView<C> getSubSequence(final Integer bioBegin, final Integer bioEnd) {
209            return new SequenceProxyView<C>(ArrayListSequenceReader.this, bioBegin, bioEnd);
210        }
211    
212     /**
213      *
214      * @return
215      */
216        public AccessionID getAccession() {
217            throw new UnsupportedOperationException("Not supported yet.");
218        }
219    /**
220     *
221     * @param compounds
222     * @return
223     */
224        
225        public int countCompounds(C... compounds) {
226           return SequenceMixin.countCompounds(this, compounds);
227        }
228    /**
229     * 
230     * @return
231     */
232        @Override
233        public SequenceView<C> getInverse() {
234            return SequenceMixin.inverse(this);
235        }
236    }