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.Map;
028
029/**
030 * A no-frills implementation of TranslationTable that uses a Map to map from
031 * symbols in a finite source alphabet into a target alphabet.
032 *
033 * @author Matthew Pocock
034 * @author David Huen (refactoring)
035 */
036public class SimpleReversibleTranslationTable 
037      extends AbstractReversibleTranslationTable
038      implements Serializable {
039  private final Map transMap;
040  private final Map revMap;
041  private final FiniteAlphabet source;
042  private final Alphabet target;
043
044  public Alphabet getSourceAlphabet() {
045    return source;
046  }
047
048  public Alphabet getTargetAlphabet() {
049    return target;
050  }
051
052  protected Symbol doTranslate(Symbol sym) {
053    return (Symbol) transMap.get(sym);
054  }
055
056  protected Symbol doUntranslate(Symbol sym) {
057    return (Symbol) revMap.get(sym);
058  }
059
060  /**
061   * Alter the translation mapping.
062   *
063   * @param from source AtomicSymbol
064   * @param to   target AtomicSymbol to be returned by translate(from)
065   * @throws IllegalSymbolException if either from is not in the source
066   *         alphabet or to is not in the target alphabet
067   */
068  public void setTranslation(AtomicSymbol from, AtomicSymbol to)
069  throws IllegalSymbolException {
070    source.validate(from);
071    target.validate(to);
072    transMap.put(from, to);
073    revMap.put(to, from);
074  }
075
076  /**
077   * Construct a new translation table.
078   *
079   * @param source  the source FiniteAlphabet
080   * @param target the target FiniteAlphabet
081   * @throws IllegalAlphabetException if the alphabets are of different sizes
082   */
083  public SimpleReversibleTranslationTable(FiniteAlphabet source, FiniteAlphabet target) 
084    throws IllegalAlphabetException
085  {
086
087    if(source.size() != target.size()) {
088      throw new IllegalAlphabetException(
089        "Couldn't create translation table as " +
090        "the alphabets were different sizes: " +
091        source.size() + ":" + source.getName() +
092        target.size() + ":" + target.getName()
093      );
094    }
095
096    this.source = source;
097    this.target = target;
098    this.transMap = new HashMap();
099    this.revMap = new HashMap();
100  }
101}