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 022 023package org.biojava.bio.dp; 024 025import java.io.Serializable; 026import java.util.Collections; 027import java.util.List; 028import java.util.Set; 029 030import org.biojava.bio.Annotatable; 031import org.biojava.bio.Annotation; 032import org.biojava.bio.dist.Distribution; 033import org.biojava.bio.symbol.Alphabet; 034import org.biojava.bio.symbol.SingletonAlphabet; 035import org.biojava.utils.AbstractChangeable; 036import org.biojava.utils.ChangeEvent; 037import org.biojava.utils.ChangeForwarder; 038import org.biojava.utils.ChangeSupport; 039import org.biojava.utils.ChangeType; 040import org.biojava.utils.ChangeVetoException; 041import org.biojava.utils.SingletonList; 042 043/** 044 * @author Matthew Pocock 045 * @author Thomas Down 046 * @author Mark Schreiber 047 */ 048public class SimpleEmissionState 049 extends 050 AbstractChangeable 051 implements 052 EmissionState, 053 Serializable 054{ 055 private Distribution dis; 056 private String name; 057 private Annotation ann; 058 private int [] advance; 059 private Alphabet matches; 060 061 protected transient ChangeForwarder annotationForwarder; 062 protected transient ChangeForwarder distForwarder; 063 064 public final Annotation getAnnotation() { 065 return this.ann; 066 } 067 068 public final void setAnnotation(Annotation ann) 069 throws ChangeVetoException{ 070 if(!hasListeners()) { 071 this.ann = ann; 072 } else { 073 ChangeEvent ce = new ChangeEvent( 074 this, EmissionState.ANNOTATION, 075 this.ann, ann 076 ); 077 ChangeSupport changeSupport = getChangeSupport(EmissionState.ANNOTATION); 078 synchronized(changeSupport) { 079 changeSupport.firePreChangeEvent(ce); 080 this.ann.removeChangeListener(annotationForwarder, Annotation.PROPERTY); 081 ann.addChangeListener(annotationForwarder, Annotation.PROPERTY); 082 this.ann = ann; 083 changeSupport.firePostChangeEvent(ce); 084 } 085 } 086 } 087 088 public final Distribution getDistribution() { 089 return this.dis; 090 } 091 092 public final void setDistribution(Distribution dis) 093 throws ChangeVetoException { 094 if(!hasListeners()) { 095 this.dis = dis; 096 } else { 097 ChangeEvent ce = new ChangeEvent( 098 this, EmissionState.DISTRIBUTION, 099 this.dis, dis 100 ); 101 ChangeSupport changeSupport = getChangeSupport(EmissionState.DISTRIBUTION); 102 synchronized(changeSupport) { 103 changeSupport.firePreChangeEvent(ce); 104 if(this.dis != null) { 105 this.dis.addChangeListener(distForwarder, Distribution.WEIGHTS); 106 this.dis.addChangeListener(distForwarder, Distribution.NULL_MODEL); 107 } 108 if(dis != null) { 109 dis.addChangeListener(distForwarder, Distribution.WEIGHTS); 110 dis.addChangeListener(distForwarder, Distribution.NULL_MODEL); 111 } 112 this.dis = dis; 113 changeSupport.firePostChangeEvent(ce); 114 } 115 } 116 } 117 118 public int [] getAdvance() { 119 return advance; 120 } 121 122 public void setAdvance(int [] advance) 123 throws ChangeVetoException { 124 if(!hasListeners()) { 125 this.advance = advance; 126 } else { 127 ChangeEvent ce = new ChangeEvent( 128 this, EmissionState.ADVANCE, 129 this.advance, advance 130 ); 131 ChangeSupport changeSupport = getChangeSupport(EmissionState.ADVANCE); 132 synchronized(changeSupport) { 133 changeSupport.firePreChangeEvent(ce); 134 this.advance = advance; 135 changeSupport.firePostChangeEvent(ce); 136 } 137 } 138 } 139 140 public char getToken() { 141 return this.name.charAt(0); 142 } 143 144 public final String getName() { 145 return this.name; 146 } 147 148 public final void setName(String name) { 149 this.name = name; 150 } 151 152 public Alphabet getMatches() { 153 return matches; 154 } 155 156 public Set getBases() { 157 return Collections.singleton(this); 158 } 159 160 public List getSymbols() { 161 return new SingletonList(this); 162 } 163 164 public SimpleEmissionState( 165 String name, 166 Annotation ann, 167 int [] advance, 168 Distribution dis 169 ) { 170 this.name = name; 171 this.ann = ann; 172 this.advance = advance; 173 this.dis = dis; 174 this.matches = new SingletonAlphabet(this); 175 } 176 177 public void registerWithTrainer(ModelTrainer trainer) { 178 trainer.registerDistribution(getDistribution()); 179 } 180 181 protected ChangeSupport getChangeSupport(ChangeType ct){ 182 ChangeSupport cs = super.getChangeSupport(ct); 183 184 if( 185 annotationForwarder == null && 186 ct.isMatchingType(Annotatable.ANNOTATION)) 187 { 188 annotationForwarder = new ChangeForwarder.Retyper(this, cs, Annotation.PROPERTY); 189 getAnnotation().addChangeListener( 190 annotationForwarder, 191 Annotatable.ANNOTATION); 192 } 193 194 if( 195 distForwarder == null && 196 ct.isMatchingType(EmissionState.DISTRIBUTION)) 197 { 198 distForwarder = new ChangeForwarder.Retyper(this, cs, EmissionState.DISTRIBUTION); 199 getDistribution().addChangeListener( 200 distForwarder, 201 Distribution.WEIGHTS); 202 getDistribution().addChangeListener( 203 distForwarder, 204 Distribution.NULL_MODEL); 205 } 206 return cs; 207 } 208}