/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.bio.program.tagvalue; import java.util.List; import java.util.Map; import org.biojava.utils.ParserException; import org.biojava.utils.SmallMap; /** *
* A mapping between keys and actions to turn old values into new values. *
* * @author Matthew Pocock * @since 1.3 */ public class ChangeTable { public static final Changer STRING_TO_INT = new Changer() { public Object change(Object val) { return new Integer((String) val); } }; private final Map changers; private final Map splitters; public ChangeTable() { this.changers = new SmallMap(); this.splitters = new SmallMap(); } /** * Set the Changer to be used for all values of a particular tag. * * @param tag the tag Object which will have all values changed * @param changer the Changer used to change the values */ public void setChanger(Object tag, Changer changer) { changers.put(tag, changer); } /** * Set the Splitter to be used for all values of a particular tag. * * @param tag the tag Object which will have all values split * @param splitter the Splitter used to split the values */ public void setSplitter(Object tag, Splitter splitter) { splitters.put(tag, splitter); } /** * Get the Changer currently registered to handle a tag. * * @param tag the tag Object for which values would be changed * @return the associated Changer or null */ public Changer getChanger(Object tag) { return (Changer) changers.get(tag); } /** * Get the Splitter currently registered to handle a tag. * * @param tag the tag Object for which values would be split * @return the associated Splitter or null */ public Splitter getSplitter(Object tag) { return (Splitter) splitters.get(tag); } public Object change(Object tag, Object value) throws ParserException { Changer c = (Changer) changers.get(tag); if(c != null) { return c.change(value); } Splitter s = (Splitter) splitters.get(tag); if(s != null) { return s.split(value); } return value; } /** * Callback used to produce a new value from an old one. * * @author Matthew Pocock * @since 1.3 */ public static interface Changer { /** ** Produce a modified value from an old value. *
* ** It is strongly recommended that this method is re-entrant and does not * modify the state of the Changer in a way that would affect future return * -values. *
* * @param value the old value Object * @return the new value Object * @throws ParserException if value could not be changed */ public Object change(Object value) throws ParserException; } /** * Callback used to produce a list of values from a single old one. * * @author Matthew Pocock * @since 1.3 */ public static interface Splitter { /** ** Produce a list of values from an old value. *
* ** It is strongly recommended that this method is re-entrant and does not * modify the state of the Splitter in a way that would affect future return * -values. *
* * @param value the old value Object * @return a List of value Objects produced by splitting the old value * Object * @throws ParserException if the value could not be split */ public List split(Object value) throws ParserException; } /** * An implementation of Changer that applies a list of Changer instances to * the value in turn. * * @author Matthew Pocock * @since 1.3 */ public static class ChainedChanger implements Changer { private Changer[] changers; public ChainedChanger(Changer[] changers) { this.changers = new Changer[changers.length]; System.arraycopy(changers, 0, this.changers, 0, changers.length); } public Object change(Object value) throws ParserException { for(int i = 0; i < changers.length; i++) { value = changers[i].change(value); } return value; } } }