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 * Create a new FASTQ formatted sequence builder configured 056 * from the specified FASTQ formatted sequence. 057 * 058 * @since 6.0.0 059 * @param fastq FASTQ formatted sequence, must not be null 060 */ 061 public FastqBuilder(final Fastq fastq) 062 { 063 if (fastq == null) 064 { 065 throw new IllegalArgumentException("fastq must not be null"); 066 } 067 withDescription(fastq.getDescription()); 068 withSequence(fastq.getSequence()); 069 withQuality(fastq.getQuality()); 070 withVariant(fastq.getVariant()); 071 } 072 073 074 /** 075 * Return the description for this FASTQ formatted sequence builder. 076 * 077 * @return the description for this FASTQ formatted sequence builder 078 */ 079 public String getDescription() 080 { 081 return description; 082 } 083 084 /** 085 * Return this FASTQ formatted sequence builder configured with the specified description. 086 * 087 * @param description description for this FASTQ formatted sequence builder, must not be null 088 * @return this FASTQ formatted sequence builder configured with the specified description 089 */ 090 public FastqBuilder withDescription(final String description) 091 { 092 if (description == null) 093 { 094 throw new IllegalArgumentException("description must not be null"); 095 } 096 this.description = description; 097 return this; 098 } 099 100 /** 101 * Return this FASTQ formatted sequence builder configured with the specified sequence. 102 * 103 * @param sequence sequence for this FASTQ formatted sequence builder, must not be null 104 * @return this FASTQ formatted sequence builder configured with the specified sequence 105 */ 106 public FastqBuilder withSequence(final String sequence) 107 { 108 if (sequence == null) 109 { 110 throw new IllegalArgumentException("sequence must not be null"); 111 } 112 if (this.sequence == null) 113 { 114 this.sequence = new StringBuilder(sequence.length()); 115 } 116 this.sequence.replace(0, this.sequence.length(), sequence); 117 return this; 118 } 119 120 /** 121 * Return this FASTQ formatted sequence builder configured with the specified sequence 122 * appended to its current sequence. 123 * 124 * @param sequence sequence to append to the sequence for this FASTQ formatted sequence builder, must not be null 125 * @return this FASTQ formatted sequence builder configured with the specified sequence 126 * appended to its current sequence 127 */ 128 public FastqBuilder appendSequence(final String sequence) 129 { 130 if (sequence == null) 131 { 132 throw new IllegalArgumentException("sequence must not be null"); 133 } 134 if (this.sequence == null) 135 { 136 this.sequence = new StringBuilder(sequence.length()); 137 } 138 this.sequence.append(sequence); 139 return this; 140 } 141 142 /** 143 * Return this FASTQ formatted sequence builder configured with the specified quality scores. 144 * 145 * @param quality quality scores for this FASTQ formatted sequence builder, must not be null 146 * @return this FASTQ formatted sequence builder configured with the specified quality scores 147 */ 148 public FastqBuilder withQuality(final String quality) 149 { 150 if (quality == null) 151 { 152 throw new IllegalArgumentException("quality must not be null"); 153 } 154 if (this.quality == null) 155 { 156 this.quality = new StringBuilder(quality.length()); 157 } 158 this.quality.replace(0, this.quality.length(), quality); 159 return this; 160 } 161 162 /** 163 * Return this FASTQ formatted sequence builder configured with the specified quality scores 164 * appended to its current quality scores. 165 * 166 * @param quality quality scores to append to the quality scores for this FASTQ formatted sequence 167 * builder, must not be null 168 * @return this FASTQ formatted sequence builder configured with the specified quality scores 169 * appended to its current quality scores 170 */ 171 public FastqBuilder appendQuality(final String quality) 172 { 173 if (quality == null) 174 { 175 throw new IllegalArgumentException("quality must not be null"); 176 } 177 if (this.quality == null) 178 { 179 this.quality = new StringBuilder(quality.length()); 180 } 181 this.quality.append(quality); 182 return this; 183 } 184 185 /** 186 * Return true if the sequence and quality scores for this FASTQ formatted sequence builder are equal in length. 187 * 188 * @return true if the sequence and quality scores for this FASTQ formatted sequence builder are equal in length 189 */ 190 public boolean sequenceAndQualityLengthsMatch() 191 { 192 if (sequence == null && quality == null) 193 { 194 return true; 195 } 196 if ((sequence != null && quality == null) || (sequence == null && quality != null)) 197 { 198 return false; 199 } 200 return sequence.length() == quality.length(); 201 } 202 203 /** 204 * Return this FASTQ formatted sequence builder configured with the specified FASTQ sequence format variant. 205 * 206 * @param variant FASTQ sequence format variant for this FASTQ formatted sequence builder, must not be null 207 * @return this FASTQ formatted sequence builder configured with the specified FASTQ sequence format variant 208 */ 209 public FastqBuilder withVariant(final FastqVariant variant) 210 { 211 if (variant == null) 212 { 213 throw new IllegalArgumentException("variant must not be null"); 214 } 215 this.variant = variant; 216 return this; 217 } 218 219 /** 220 * Build and return a new FASTQ formatted sequence configured from the properties of this builder. 221 * 222 * @return a new FASTQ formatted sequence configured from the properties of this builder 223 * @throws IllegalStateException if the configuration of this builder results in an illegal state 224 */ 225 public Fastq build() 226 { 227 if (description == null) 228 { 229 throw new IllegalStateException("description must not be null"); 230 } 231 if (sequence == null) 232 { 233 throw new IllegalStateException("sequence must not be null"); 234 } 235 if (quality == null) 236 { 237 throw new IllegalStateException("quality must not be null"); 238 } 239 if (!sequenceAndQualityLengthsMatch()) 240 { 241 throw new IllegalStateException("sequence and quality scores must be the same length"); 242 } 243 Fastq fastq = new Fastq(description, sequence.toString(), quality.toString(), variant); 244 return fastq; 245 } 246}