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 */ 021 022package org.biojava.bio.seq; 023 024import java.util.Iterator; 025import java.util.List; 026 027import org.biojava.bio.Annotatable; 028import org.biojava.bio.Annotation; 029import org.biojava.bio.BioException; 030import org.biojava.bio.SimpleAnnotation; 031import org.biojava.bio.seq.impl.NewAssembledSymbolList; 032import org.biojava.bio.symbol.Alphabet; 033import org.biojava.bio.symbol.Edit; 034import org.biojava.bio.symbol.IllegalAlphabetException; 035import org.biojava.bio.symbol.Location; 036import org.biojava.bio.symbol.Symbol; 037import org.biojava.bio.symbol.SymbolList; 038import org.biojava.utils.AbstractChangeable; 039import org.biojava.utils.ChangeForwarder; 040import org.biojava.utils.ChangeSupport; 041import org.biojava.utils.ChangeType; 042import org.biojava.utils.ChangeVetoException; 043 044/** 045 * A Sequence which is assembled from other sequences contained 046 * in a set of ComponentFeature objects. 047 * <p> 048 * The class has been extended to handle overlapping 049 * component sequences. It is assumed that the overlaps 050 * are consistent between components: this will not be checked. 051 * <p> 052 * There is still some potential for optimising SymbolList 053 * operations on this class. 054 * </p> 055 * 056 * @author Thomas Down 057 * @author Matthew Pocock 058 * @author David Huen 059 * @since 1.1 060 */ 061 062public class NewSimpleAssembly 063 extends 064 AbstractChangeable 065 implements 066 Sequence, 067 RealizingFeatureHolder 068{ 069 private String name; 070 private String uri; 071 private Annotation annotation = new SimpleAnnotation(); 072 private SimpleFeatureHolder features; 073 private NewAssembledSymbolList assembly; 074 075 private FeatureRealizer featureRealizer = org.biojava.bio.seq.impl.FeatureImpl.DEFAULT; 076 protected transient ChangeForwarder annotationForwarder; 077 078 { 079 assembly = new NewAssembledSymbolList(); 080 features = new SimpleFeatureHolder(); 081 } 082 083 /** 084 * Construct a new SimpleAssembly using the DNA alphabet. 085 * Initially, the sequence will just contain a list of `N's. 086 * Sequence data can be added by adding one or more 087 * ComponentFeatures. 088 * 089 * @param length The length of the sequence 090 * @param name The name of the sequence (returned by getName()) 091 * @param uri The identifier of the sequence (returned by getURN()); 092 */ 093 094 public NewSimpleAssembly(int length, String name, String uri) { 095 this.name = name; 096 this.uri = uri; 097 assembly.setLength(length); 098 } 099 100 /** 101 * Construct a new NewSimpleAssembly using the DNA alphabet. 102 * Initially, the sequence will just contain a list of `N's. 103 * Sequence data can be added by adding one or more 104 * ComponentFeatures. 105 * 106 * @param name The name of the sequence (returned by getName()) 107 * @param uri The identifier of the sequence (returned by getURN()); 108 */ 109 110 public NewSimpleAssembly(String name, String uri) { 111 this.name = name; 112 this.uri = uri; 113 } 114 115 // 116 // SymbolList 117 // 118 119 public Alphabet getAlphabet() { 120 return assembly.getAlphabet(); 121 } 122 123 public int length() { 124 return assembly.length(); 125 } 126 127 public Symbol symbolAt(int pos) { 128 return assembly.symbolAt(pos); 129 } 130 131 public SymbolList subList(int start, int end) { 132 return assembly.subList(start, end); 133 } 134 135 public String seqString() { 136 return assembly.seqString(); 137 } 138 139 public String subStr(int start, int end) { 140 return assembly.subStr(start, end); 141 } 142 143 public Iterator iterator() { 144 return assembly.iterator(); 145 } 146 147 public List toList() { 148 return assembly.toList(); 149 } 150 151 public void edit(Edit e) 152 throws IllegalAlphabetException, ChangeVetoException 153 { 154 assembly.edit(e); 155 } 156 157 // 158 // Sequence identification 159 // 160 161 public String getName() { 162 return name; 163 } 164 165 public String getURN() { 166 return uri; 167 } 168 169 // 170 // Annotatable 171 // 172 173 public Annotation getAnnotation() { 174 return annotation; 175 } 176 177 // 178 // FeatureHolder 179 // 180 181 public Iterator features() { 182 return features.features(); 183 } 184 185 public int countFeatures() { 186 return features.countFeatures(); 187 } 188 189 public FeatureHolder filter(FeatureFilter ff, boolean recurse) { 190 return features.filter(ff, recurse); 191 } 192 193 public FeatureHolder filter(FeatureFilter ff) { 194 return features.filter(ff); 195 } 196 197 public boolean containsFeature(Feature f) { 198 return features.containsFeature(f); 199 } 200 201 public Feature createFeature(Feature.Template temp) 202 throws BioException, ChangeVetoException 203 { 204 if (temp.location.getMin() < 1) 205 throw new BioException("Coordinates out of range"); 206 207 Feature f = realizeFeature(this, temp); 208 features.addFeature(f); 209 if (f instanceof ComponentFeature) { 210 ComponentFeature cf = (ComponentFeature) f; 211 Location loc = cf.getLocation(); 212 if (loc.getMax() > assembly.length()) { 213 assembly.setLength(loc.getMax()); 214 } 215 assembly.putComponent(cf); 216// System.out.println(assembly.getComponentLocationSet()); 217 } 218 return f; 219 } 220 221 222 public void removeFeature(Feature f) 223 throws ChangeVetoException { 224 if (f instanceof ComponentFeature) { 225 assembly.removeComponent((ComponentFeature) f); 226 } 227 features.removeFeature(f); 228 } 229 230 // 231 // Feature realization 232 // 233 234 public Feature realizeFeature(FeatureHolder fh, Feature.Template temp) 235 throws BioException 236 { 237 if (temp instanceof ComponentFeature.Template) { 238 if (fh != this) { 239 throw new BioException("ComponentFeatures can only be attached directly to SimpleAssembly objects"); 240 } 241 ComponentFeature.Template cft = (ComponentFeature.Template) temp; 242 return new SimpleComponentFeature(this, cft); 243 } else { 244 FeatureHolder gopher = fh; 245 while (gopher instanceof Feature) { 246 if (gopher instanceof ComponentFeature) { 247 throw new BioException("Cannot [currently] realize features on components of SimpleAssemblies"); 248 } 249 gopher = ((Feature) gopher).getParent(); 250 } 251 return featureRealizer.realizeFeature(this, fh, temp); 252 } 253 } 254 255 protected ChangeSupport getChangeSupport(ChangeType ct){ 256 ChangeSupport cs = super.getChangeSupport(ct); 257 258 if(annotationForwarder == null && 259 (ct == null || ct == Annotatable.ANNOTATION)){ 260 annotationForwarder = 261 new ChangeForwarder.Retyper(this, cs, Annotation.PROPERTY); 262 getAnnotation().addChangeListener( 263 annotationForwarder, 264 Annotatable.ANNOTATION); 265 } 266 return cs; 267 } 268 269 public FeatureFilter getSchema() { 270 return FeatureFilter.top_level; 271 } 272}