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.biojavax;
023
024import org.biojava.utils.AbstractChangeable;
025import org.biojava.utils.ChangeEvent;
026import org.biojava.utils.ChangeSupport;
027import org.biojava.utils.ChangeVetoException;
028
029/**
030 * Simple implementation of RankedCrossRef.
031 * @author Richard Holland
032 * @author gwaldon
033 * @since 1.5
034 */
035public class SimpleRankedCrossRef extends AbstractChangeable implements RankedCrossRef {
036    
037    private CrossRef crossref;
038    private int rank;
039    
040    /**
041     * Constructs a new crossref with a rank.
042     * @param crossref the crossref to rank. Must not be null.
043     * @param rank the rank to give it.
044     */
045    public SimpleRankedCrossRef(CrossRef crossref, int rank) {
046        if (crossref==null) throw new IllegalArgumentException("Cross reference cannot be null");
047        this.crossref = crossref;
048        this.rank = rank;
049    }
050    
051    // Hibernate requirement - not for public use.
052    protected SimpleRankedCrossRef() {}
053    
054    // Hibernate requirement - not for public use.
055    void setCrossRef(CrossRef crossref) { this.crossref = crossref; }
056    
057    /**
058     * {@inheritDoc}
059     */
060    public CrossRef getCrossRef() { return this.crossref; }
061    
062    /**
063     * {@inheritDoc}
064     */
065    public void setRank(int rank)  throws ChangeVetoException {
066        if(rank==this.rank)
067            return;
068        if(!this.hasListeners(RankedCrossRef.RANK)) {
069            this.rank = rank;
070        } else {
071            ChangeEvent ce = new ChangeEvent(
072                    this,
073                    RankedCrossRef.RANK,
074                    new Integer(rank),
075                    new Integer(this.rank)
076                    );
077            ChangeSupport cs = this.getChangeSupport(RankedCrossRef.RANK);
078            synchronized(cs) {
079                cs.firePreChangeEvent(ce);
080                this.rank = rank;
081                cs.firePostChangeEvent(ce);
082            }
083        }
084    }
085    
086    /**
087     * {@inheritDoc}
088     */
089    public int getRank() { return this.rank; }
090    
091    /**
092     * {@inheritDoc}
093     * Ranked cross references are the same if they have the same rank and
094     * refer to the same cross reference (cross references are equal).
095     */
096    public boolean equals(Object obj) {
097        if (this == obj) return true;
098        if (obj==null || !(obj instanceof RankedCrossRef)) return false;
099        // Hibernate comparison - we haven't been populated yet
100        if (this.crossref==null) return false;
101        // Normal comparison
102        RankedCrossRef them = (RankedCrossRef)obj;
103        return (this.rank==them.getRank() &&
104                this.crossref.equals(them.getCrossRef()));
105    }
106    
107    /**
108     * {@inheritDoc}
109     * Ranked cross references are sorted first by rank, then by cross reference.
110     */
111    public int compareTo(Object o) {
112        if (o==this) return 0;
113        // Hibernate comparison - we haven't been populated yet
114        if (this.crossref==null) return -1;
115        // Normal comparison
116        RankedCrossRef them = (RankedCrossRef)o;
117        if (this.rank!=them.getRank()) return this.rank - them.getRank();
118        return this.crossref.compareTo(them.getCrossRef());
119    }
120    
121    /**
122     * {@inheritDoc}
123     */
124    public int hashCode() {
125        int code = 17;
126        // Hibernate comparison - we haven't been populated yet
127        if (this.crossref==null) return code;
128        // Normal comparison
129        code = 37*code + this.crossref.hashCode();
130        code = 37*code + this.rank;
131        return code;
132    }
133    
134    /**
135     * {@inheritDoc}
136     * Form: "(#rank) crossref"
137     */
138    public String toString() {
139        return "(#"+this.rank+") "+this.crossref;
140    }
141}