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;
028import org.biojavax.ontology.ComparableTerm;
029
030/**
031 * Simple implementation of Note.
032 * @author Richard Holland
033 * @author George Waldon - limited firing
034 * @since 1.5
035 */
036public class SimpleNote extends AbstractChangeable implements Note {
037    
038    private ComparableTerm term;
039    private String value;
040    private int rank;
041    
042    /**
043     * Creates a new instance of SimpleNote with a given term, value and rank.
044     * @param term the term of the note. Cannot be null.
045     * @param value the (optional) value to give it.
046     * @param rank the rank to give it.
047     */
048    public SimpleNote(ComparableTerm term, String value, int rank) {
049        if (term==null) throw new IllegalArgumentException("Term cannot be null");
050        this.term = term;
051        this.value = value;
052        this.rank = rank;
053    }
054    
055    // Hibernate requirement - not for public use.
056    protected SimpleNote() {}
057    
058    /**
059     * {@inheritDoc}
060     */
061    public ComparableTerm getTerm() { return this.term; }
062    
063    /**
064     * {@inheritDoc}
065     */
066    public void setTerm(ComparableTerm term) throws ChangeVetoException {
067        if (term==null) throw new IllegalArgumentException("Term cannot be null");
068        if(term.equals(this.term))
069            return;
070        if(!this.hasListeners(Note.TERM)) {
071            this.term = term;
072        } else {
073            ChangeEvent ce = new ChangeEvent(
074                    this,
075                    Note.TERM,
076                    term,
077                    this.term
078                    );
079            ChangeSupport cs = this.getChangeSupport(Note.TERM);
080            synchronized(cs) {
081                cs.firePreChangeEvent(ce);
082                this.term = term;
083                cs.firePostChangeEvent(ce);
084            }
085        }
086    }
087    
088    /**
089     * {@inheritDoc}
090     */
091    public String getValue() { return this.value; }
092    
093    /**
094     * {@inheritDoc}
095     */
096    public void setValue(String value) throws ChangeVetoException {
097        if(this.value!=null && this.value.equals(value)) return;
098        else if(this.value==null && value==null) return;
099        
100        if(!this.hasListeners(Note.VALUE)) {
101            this.value = value;
102        } else {
103            ChangeEvent ce = new ChangeEvent(
104                    this,
105                    Note.VALUE,
106                    value,
107                    this.value
108                    );
109            ChangeSupport cs = this.getChangeSupport(Note.VALUE);
110            synchronized(cs) {
111                cs.firePreChangeEvent(ce);
112                this.value = value;
113                cs.firePostChangeEvent(ce);
114            }
115        }
116    }
117    
118    /**
119     * {@inheritDoc}
120     */
121    public int getRank() { return this.rank; }
122    
123    /**
124     * {@inheritDoc}
125     */
126    public void setRank(int rank) throws ChangeVetoException {
127        if(this.rank==rank) 
128            return;
129        if(!this.hasListeners(Note.RANK)) {
130            this.rank = rank;
131        } else {
132            ChangeEvent ce = new ChangeEvent(
133                    this,
134                    Note.RANK,
135                    new Integer(rank),
136                    new Integer(this.rank)
137                    );
138            ChangeSupport cs = this.getChangeSupport(Note.RANK);
139            synchronized(cs) {
140                cs.firePreChangeEvent(ce);
141                this.rank = rank;
142                cs.firePostChangeEvent(ce);
143            }
144        }
145    }
146    
147    /**
148     * {@inheritDoc}
149     * Notes are compared first by rank, then by the term.
150     */
151    public int compareTo(Object o) {
152        if (o==this) return 0;
153        // Hibernate comparison - we haven't been populated yet
154        if (this.term==null) return -1;
155        // Normal comparison
156        Note them = (Note)o;
157        if (this.rank!=them.getRank()) return this.rank-them.getRank();
158        else return this.term.compareTo(them.getTerm());
159    }
160    
161    /**
162     * {@inheritDoc}
163     * Notes are equal if they have the same rank and term.
164     */
165    public boolean equals(Object o) {
166        if (o==this) return true;
167        if (!(o instanceof Note)) return false;
168        // Hibernate comparison - we haven't been populated yet
169        if (this.term==null) return false;
170        // Normal comparison
171        Note them = (Note)o;
172        return this.term.equals(them.getTerm()) && this.rank==them.getRank();
173    }
174    
175    /**
176     * {@inheritDoc}
177     */
178    public int hashCode() {
179        int hash = 17;
180        // Hibernate comparison - we haven't been populated yet
181        if (this.term==null) return hash;
182        // Normal comparison
183        hash = 31*hash + this.term.hashCode();
184        hash = 31*hash + this.rank;
185        return hash;
186    }
187    
188    /**
189     * {@inheritDoc}
190     * Form: "(#rank) term: value"
191     */
192    public String toString() {
193        return "(#"+this.rank+") "+this.term+": "+this.value;
194    }
195}