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
022package org.biojava.bio.seq.homol;
023 
024import java.util.Iterator;
025
026import org.biojava.bio.BioException;
027import org.biojava.bio.alignment.Alignment;
028import org.biojava.bio.seq.Feature;
029import org.biojava.bio.seq.FeatureHolder;
030import org.biojava.bio.seq.SimpleFeatureHolder;
031import org.biojava.utils.AbstractChangeable;
032import org.biojava.utils.ChangeEvent;
033import org.biojava.utils.ChangeSupport;
034import org.biojava.utils.ChangeVetoException;
035
036/**
037 * A no-frills implementation of Homology.
038 *
039 * @author Matthew Pocock
040 * @author <a href="mailto:kdj@sanger.ac.uk">Keith James</a>
041 * @since 1.2
042 */
043public class SimpleHomology extends AbstractChangeable implements Homology
044{
045    private SimpleFeatureHolder features;
046    private Alignment           alignment;
047
048    /**
049     * Creates a new empty <code>SimpleHomology</code> containing no
050     * <code>Alignment</code> and no <code>FeatureHolder</code>.
051     */
052    public SimpleHomology() { }
053
054    /**
055     * <code>getFeatures</code> returns the constituent
056     * <code>HomologyFeature</code>s which are also used as the keys
057     * in the alignment.
058     *
059     * @return a <code>FeatureHolder</code>.
060     */
061    public FeatureHolder getFeatures()
062    {
063        return features;
064    }
065
066    /**
067     * <code>getAlignment</code> returns the alignment, which uses the
068     * <code>HomologyFeature</code>s as keys.
069     *
070     * @return an <code>Alignment</code>.
071     */
072    public Alignment getAlignment()
073    {
074        return alignment;
075    }
076
077    /**
078     * <code>setAlignment</code> sets the alignment which describes
079     * the homology. The alignment, should use the
080     * <code>HomologyFeature</code>s as keys. A suitable
081     * <code>FeatureHolder</code> is automatically created.
082     *
083     * @param alignment an <code>Alignment</code>.
084     *
085     * @exception BioException if an error occurs.
086     * @exception ChangeVetoException if the
087     * <code>SimpleHomology</code> is locked.
088     */
089    public void setAlignment(Alignment alignment)
090        throws BioException, ChangeVetoException
091    {
092        if (hasListeners())
093        {
094            ChangeSupport cs = getChangeSupport(Homology.ALIGNMENT);
095
096            ChangeEvent ce = new ChangeEvent(this, Homology.ALIGNMENT,
097                                             alignment, this.alignment);
098
099            synchronized(cs)
100            {
101              cs.firePreChangeEvent(ce);
102              this.alignment = alignment;
103              cs.firePostChangeEvent(ce);
104            }  
105        }
106        else
107        {
108            this.alignment = alignment;
109        }
110
111        features = new SimpleFeatureHolder();
112
113        for (Iterator li = alignment.getLabels().iterator(); li.hasNext();)
114        {
115            Object o = li.next();
116            if (! HomologyFeature.class.isInstance(o))
117                throw new BioException("The labels of the Alignment used to construct a SimpleHomology should be the relevant HomologyFeatures");
118
119            features.addFeature((Feature) o);
120        }
121    }
122
123    public String toString()
124    {
125        return "SimpleHomology [" + alignment.getLabels().size() + " features]";
126    }
127}