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.bio.seq; 022 023import java.io.NotSerializableException; 024import java.io.ObjectStreamException; 025import java.io.Serializable; 026 027import org.biojava.bio.symbol.SymbolList; 028import org.biojava.utils.ChangeType; 029import org.biojava.utils.ChangeVetoException; 030import org.biojava.utils.StaticMemberPlaceHolder; 031 032/** 033 * Adds the concept of 'strand' to features. 034 * <p> 035 * Strandedness only applies to some types of sequence, such as DNA. Any 036 * implementation should blow chunks to avoid being added to a sequence for 037 * which strand is a foreign concept. 038 * 039 * Strand is intrinsicly part of all {@link org.biojavax.bio.seq.RichFeature RichFeatures} 040 * We strongly recommend using this interface. 041 * 042 * @author Matthew Pocock 043 *@see org.biojavax.bio.seq.RichFeature 044 */ 045public interface StrandedFeature extends Feature { 046 047 /** 048 * The strand of this feature is being altered. 049 */ 050 public static final ChangeType STRAND = 051 new ChangeType("Strand has altered", StrandedFeature.class, "STRAND"); 052 053 /** 054 * Retrieve the strand that this feature lies upon. 055 * <p> 056 * This will be one of StrandedFeature.POSITIVE or NEGATIVE. 057 * 058 * @return one of the Strand constants 059 */ 060 Strand getStrand(); 061 062 /** 063 * Set the strand that this feature lies upon. 064 * <p> 065 * This will be one of StrandedFeature.POSITIVE or NEGATIVE. 066 * 067 * @param strand a <code>Strand</code>. 068 * 069 * @exception ChangeVetoException if the strand may not be 070 * changed. 071 */ 072 void setStrand(Strand strand) throws ChangeVetoException; 073 074 /** 075 * Return a list of symbols that are contained in this feature. 076 * <p> 077 * The symbols may not be contiguous in the original sequence, but they 078 * will be concatenated together in the resulting SymbolList. 079 * <p> 080 * The order of the Symbols within the resulting symbol list will be 081 * according to the concept of ordering within the location object. 082 * <p> 083 * If the feature is on the negative strand then the SymbolList will be 084 * reverse-complemented as appropriate. 085 * 086 * @return a SymbolList containing each symbol of the parent sequence contained 087 * within this feature in the order they appear in the parent 088 */ 089 SymbolList getSymbols(); 090 091 /** 092 * Flag to indicate that a feature is on the positive strand. 093 */ 094 static final Strand POSITIVE = new Strand("POSITIVE", +1, '+'); 095 096 /** 097 * Flag to indicate that a feature is on the negative strand. 098 */ 099 static final Strand NEGATIVE = new Strand("NEGATIVE", -1, '-'); 100 101 /** 102 * Flag to indicate that a feature has an unknown strand. 103 */ 104 static final Strand UNKNOWN = new Strand("UNKNOWN", 0, '.'); 105 106 /** 107 * Template class for parameterizing the creation of a new 108 * <code>StrandedFeature</code>. 109 * 110 * @author Matthew Pocock 111 */ 112 113 public static class Template extends Feature.Template { 114 public Strand strand; 115 } 116 117 /** 118 * Class to represent the 'strandedness' of a feature. 119 * <p> 120 * Strandedness may be re-used in other situations, but basically what it means 121 * is whether the feature has directionality, and if it does, does it travel 122 * from its location min to max, or max to min. 123 * 124 * @author Matthew Pocock 125 */ 126 public static final class Strand implements Serializable { 127 private final String text; 128 private final int value; 129 private final char token; 130 131 // Should be private. workaround for known javac 1.2 bug 132 // http://developer.java.sun.com/developer/bugParade/bugs/4262105.html 133 Strand(String text, int value, char token) { 134 this.text = text; 135 this.value = value; 136 this.token = token; 137 } 138 public String toString() { 139 return text; 140 } 141 142 /** 143 * Returns the integer label for strandedness. That is, "+1", "-1", 144 * or "0" for positive, negative, and unknown strands respectively. 145 */ 146 public int getValue() { 147 return value; 148 } 149 150 /** 151 * Returns the token for strandedness. That is, "+","-","." for 152 * positive, negative and unknown strands respectively. 153 */ 154 public char getToken() { 155 return token; 156 } 157 158 /** 159 * Return a strand that represents flipping this onto the opposite strand. 160 */ 161 public Strand flip() { 162 if(this == POSITIVE) { 163 return NEGATIVE; 164 } else if(this == NEGATIVE) { 165 return POSITIVE; 166 } else { 167 return this; 168 } 169 } 170 171 private Object writeReplace() throws ObjectStreamException { 172 try { 173 return new StaticMemberPlaceHolder(StrandedFeature.class.getField(text)); 174 } catch (NoSuchFieldException nsfe) { 175 throw new NotSerializableException(nsfe.getMessage()); 176 } 177 } 178 } 179}