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.genome.io.fastq;
022
023/**
024 * Fluent builder API for creating FASTQ formatted sequences.
025 *
026 * @since 3.0.3
027 */
028public final class FastqBuilder
029{
030        /** Description for this FASTQ formatted sequence builder. */
031        private String description;
032
033        /** Sequence for this FASTQ formatted sequence builder. */
034        private StringBuilder sequence;
035
036        /** Quality scores for this FASTQ formatted sequence builder. */
037        private StringBuilder quality;
038
039        /** FASTQ sequence format variant for this FASTQ formatted sequence builder. */
040        private FastqVariant variant = DEFAULT_VARIANT;
041
042        /** Default FASTQ sequence format variant, <code>FastqVariant.FASTQ_SANGER</code>. */
043        public static final FastqVariant DEFAULT_VARIANT = FastqVariant.FASTQ_SANGER;
044
045
046        /**
047         * Create a new FASTQ formatted sequence builder.
048         */
049        public FastqBuilder()
050        {
051                // empty
052        }
053
054
055        /**
056         * Return the description for this FASTQ formatted sequence builder.
057         *
058         * @return the description for this FASTQ formatted sequence builder
059         */
060        public String getDescription()
061        {
062                return description;
063        }
064
065        /**
066         * Return this FASTQ formatted sequence builder configured with the specified description.
067         *
068         * @param description description for this FASTQ formatted sequence builder, must not be null
069         * @return this FASTQ formatted sequence builder configured with the specified description
070         */
071        public FastqBuilder withDescription(final String description)
072        {
073                if (description == null)
074                {
075                        throw new IllegalArgumentException("description must not be null");
076                }
077                this.description = description;
078                return this;
079        }
080
081        /**
082         * Return this FASTQ formatted sequence builder configured with the specified sequence.
083         *
084         * @param sequence sequence for this FASTQ formatted sequence builder, must not be null
085         * @return this FASTQ formatted sequence builder configured with the specified sequence
086         */
087        public FastqBuilder withSequence(final String sequence)
088        {
089                if (sequence == null)
090                {
091                        throw new IllegalArgumentException("sequence must not be null");
092                }
093                if (this.sequence == null)
094                {
095                        this.sequence = new StringBuilder(sequence.length());
096                }
097                this.sequence.replace(0, this.sequence.length(), sequence);
098                return this;
099        }
100
101        /**
102         * Return this FASTQ formatted sequence builder configured with the specified sequence
103         * appended to its current sequence.
104         *
105         * @param sequence sequence to append to the sequence for this FASTQ formatted sequence builder, must not be null
106         * @return this FASTQ formatted sequence builder configured with the specified sequence
107         *    appended to its current sequence
108         */
109        public FastqBuilder appendSequence(final String sequence)
110        {
111                if (sequence == null)
112                {
113                        throw new IllegalArgumentException("sequence must not be null");
114                }
115                if (this.sequence == null)
116                {
117                        this.sequence = new StringBuilder(sequence.length());
118                }
119                this.sequence.append(sequence);
120                return this;
121        }
122
123        /**
124         * Return this FASTQ formatted sequence builder configured with the specified quality scores.
125         *
126         * @param quality quality scores for this FASTQ formatted sequence builder, must not be null
127         * @return this FASTQ formatted sequence builder configured with the specified quality scores
128         */
129        public FastqBuilder withQuality(final String quality)
130        {
131                if (quality == null)
132                {
133                        throw new IllegalArgumentException("quality must not be null");
134                }
135                if (this.quality == null)
136                {
137                        this.quality = new StringBuilder(quality.length());
138                }
139                this.quality.replace(0, this.quality.length(), quality);
140                return this;
141        }
142
143        /**
144         * Return this FASTQ formatted sequence builder configured with the specified quality scores
145         * appended to its current quality scores.
146         *
147         * @param quality quality scores to append to the quality scores for this FASTQ formatted sequence
148         *    builder, must not be null
149         * @return this FASTQ formatted sequence builder configured with the specified quality scores
150         *    appended to its current quality scores
151         */
152        public FastqBuilder appendQuality(final String quality)
153        {
154                if (quality == null)
155                {
156                        throw new IllegalArgumentException("quality must not be null");
157                }
158                if (this.quality == null)
159                {
160                        this.quality = new StringBuilder(quality.length());
161                }
162                this.quality.append(quality);
163                return this;
164        }
165
166        /**
167         * Return true if the sequence and quality scores for this FASTQ formatted sequence builder are equal in length.
168         *
169         * @return true if the sequence and quality scores for this FASTQ formatted sequence builder are equal in length
170         */
171        public boolean sequenceAndQualityLengthsMatch()
172        {
173                if (sequence == null && quality == null)
174                {
175                        return true;
176                }
177                if ((sequence != null && quality == null) || (sequence == null && quality != null))
178                {
179                        return false;
180                }
181                return sequence.length() == quality.length();
182        }
183
184        /**
185         * Return this FASTQ formatted sequence builder configured with the specified FASTQ sequence format variant.
186         *
187         * @param variant FASTQ sequence format variant for this FASTQ formatted sequence builder, must not be null
188         * @return this FASTQ formatted sequence builder configured with the specified FASTQ sequence format variant
189         */
190        public FastqBuilder withVariant(final FastqVariant variant)
191        {
192                if (variant == null)
193                {
194                        throw new IllegalArgumentException("variant must not be null");
195                }
196                this.variant = variant;
197                return this;
198        }
199
200        /**
201         * Build and return a new FASTQ formatted sequence configured from the properties of this builder.
202         *
203         * @return a new FASTQ formatted sequence configured from the properties of this builder
204         * @throws IllegalStateException if the configuration of this builder results in an illegal state
205         */
206        public Fastq build()
207        {
208                if (description == null)
209                {
210                        throw new IllegalStateException("description must not be null");
211                }
212                if (sequence == null)
213                {
214                        throw new IllegalStateException("sequence must not be null");
215                }
216                if (quality == null)
217                {
218                        throw new IllegalStateException("quality must not be null");
219                }
220                if (!sequenceAndQualityLengthsMatch())
221                {
222                        throw new IllegalStateException("sequence and quality scores must be the same length");
223                }
224                Fastq fastq = new Fastq(description, sequence.toString(), quality.toString(), variant);
225                return fastq;
226        }
227}