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.symbol; 024 025import java.io.Serializable; 026import java.util.HashMap; 027import java.util.HashSet; 028import java.util.Map; 029import java.util.Set; 030 031/** 032 * A no-frills implementation of a translation table that 033 * maps between two alphabets. The mapping can be either 034 * one-to-one or many-to-one. 035 * 036 * @author David Huen 037 */ 038public class SimpleManyToOneTranslationTable 039 extends AbstractManyToOneTranslationTable 040 implements Serializable { 041 private final Map transMap; 042 private final Map revMap; 043 private final FiniteAlphabet source; 044 private final Alphabet target; 045 046 public Alphabet getSourceAlphabet() { 047 return source; 048 } 049 050 public Alphabet getTargetAlphabet() { 051 return target; 052 } 053 054 protected Symbol doTranslate(Symbol sym) { 055 return (Symbol) transMap.get(sym); 056 } 057 058 protected Set doUntranslate(Symbol sym) { 059 return (Set) revMap.get(sym); 060 } 061 062 /** 063 * Alter the translation mapping. 064 * 065 * @param from source AtomicSymbol 066 * @param to target AtomicSymbol to be returned by translate(from) 067 * @throws IllegalSymbolException if either from is not in the source 068 * alphabet or to is not in the target alphabet 069 */ 070 public void setTranslation(AtomicSymbol from, AtomicSymbol to) 071 throws IllegalSymbolException { 072 073 source.validate(from); 074 target.validate(to); 075 076 // when putting in a association in a many-to-one 077 // you will need to verify that an existing relation does 078 // not exist: otherwise you will need to remove it prior 079 // to putting in the new one. 080 081 // do I have an existing association for this symbol? 082 Symbol prevTransSymbol = doTranslate(from); 083 084 if (prevTransSymbol != null) { 085 // there is an association, I need to 086 // remove the previous target Symbol 087 // from the unTranslate mapping 088 // before introducing new mapping. 089 090 Set prevUntransSet = (Set) revMap.get(prevTransSymbol); 091 prevUntransSet.remove(from); 092 } 093 094 // now enter in the new association 095 Set sourceSet = (Set) revMap.get(to); 096 097 if (sourceSet == null) { 098 // create new set 099 sourceSet = new HashSet(); 100 revMap.put(to, sourceSet); 101 } 102 103 sourceSet.add(from); 104 105 transMap.put(from, to); 106 107 } 108 109 /** 110 * Construct a new translation table. 111 * 112 * @param source the source FiniteAlphabet 113 * @param target the target FiniteAlphabet 114 */ 115 public SimpleManyToOneTranslationTable(FiniteAlphabet source, FiniteAlphabet target) 116 { 117 118 this.source = source; 119 this.target = target; 120 this.transMap = new HashMap(); 121 this.revMap = new HashMap(); 122 } 123}