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 java.io.NotSerializableException;
025import java.io.ObjectStreamException;
026import java.io.Serializable;
027import java.util.Collections;
028import java.util.HashMap;
029import java.util.Map;
030import java.util.NoSuchElementException;
031import java.util.Set;
032
033import org.biojava.utils.ChangeVetoException;
034import org.biojava.utils.StaticMemberPlaceHolder;
035import org.biojava.utils.Unchangeable;
036
037/**
038 * A place holder for a RichAnnotation that prevents null having to be used
039 * @author Mark Schreiber
040 * @author Richard Holland
041 * @since 1.5
042 */
043public class EmptyRichAnnotation extends Unchangeable implements RichAnnotation, Serializable {
044    
045    private Note[] emptyNotes = new Note[]{};
046    
047    /**
048     * {@inheritDoc} There are no properties in the Empty RichAnnotation object.
049     * Calling this will return null.
050     */
051    public Object getProperty(Object key) throws NoSuchElementException {
052        return null;
053    }
054    
055    /**
056     * {@inheritDoc} There are no properties in the Empty RichAnnotation object.
057     * Calling this will return an empty array.
058     */
059    public Note[] getProperties(Object key) {
060        return this.emptyNotes;
061    }
062    
063    /**
064     * {@inheritDoc} There are no notes in the Empty RichAnnotation object.
065     * Calling this will return null.
066     */
067    public Note getNote(Note note){
068        return null;
069    }
070    
071    /**
072     * {@inheritDoc} You can not add properties to the Empty RichAnnotation object
073     * @throws ChangeVetoException whenever you call this method.
074     */
075    public void setProperty(Object key, Object value)
076    throws ChangeVetoException {
077        throw new ChangeVetoException(
078                "You can not add properties to the Empty RichAnnotation object: " +
079                key + " -> " + value
080                );
081    }
082    
083    /**
084     * {@inheritDoc} You can not add Notes to the Empty RichAnnotation object.
085     * @throws ChangeVetoException whenever you call this method.
086     */
087    public void setNoteSet(Set notes) throws ChangeVetoException{
088        throw new ChangeVetoException(
089                "You can not add Notes to the Empty RichAnnotation object");
090    }
091    
092    /**
093     * {@inheritDoc} You can not add Notes to the Empty RichAnnotation object.
094     * @throws ChangeVetoException whenever you call this method.
095     */
096    public void addNote(Note note) throws ChangeVetoException{
097        throw new ChangeVetoException(
098                "You can not add Notes to the Empty RichAnnotation object");
099    }
100    
101    /**
102     * {@inheritDoc} Does nothing as it contains nothing.
103     */
104    public void clear() throws ChangeVetoException{ }
105    
106    
107    /**
108     * {@inheritDoc} You cannot remove properties from the Empty RichAnnotation
109     * @throws ChangeVetoException whenever you call this method.
110     */
111    public void removeProperty(Object key)
112    throws ChangeVetoException {
113        throw new ChangeVetoException(
114                "You cannot remove properties from the Empty RichAnnotation (!)"
115                );
116    }
117    
118    /**
119     * {@inheritDoc} You cannot remove notes from the Empty RichAnnotation
120     * @throws ChangeVetoException whenever you call this method.
121     */
122    public void removeNote(Note note)
123    throws ChangeVetoException {
124        throw new ChangeVetoException(
125                "You cannot remove notes from the Empty RichAnnotation (!)"
126                );
127    }
128    
129    /**
130     * {@inheritDoc}
131     * @return always false as there are no properties
132     */
133    public boolean containsProperty(Object key) {
134        return false;
135    }
136    
137    /**
138     * {@inheritDoc}
139     * @return always false as there are no notes
140     */
141    public boolean contains(Note note){
142        return false;
143    }
144    
145    /**
146     * {@inheritDoc}
147     * @return an empty set
148     */
149    public Set keys() {
150        return Collections.EMPTY_SET;
151    }
152    
153    /**
154     * {@inheritDoc}
155     * @return an empty set
156     */
157    public Set getNoteSet(){
158        return Collections.EMPTY_SET;
159    }
160    
161    /**
162     * {@inheritDoc}
163     * @return an new Map with no entries
164     */
165    public Map asMap() {
166        return new HashMap();
167    }
168    
169    // For use during serialization
170    private Object writeReplace() throws ObjectStreamException {
171        try {
172            return new StaticMemberPlaceHolder(RichAnnotation.class.getField("EMPTY_ANNOTATION"));
173        } catch (NoSuchFieldException nsfe) {
174            throw new NotSerializableException(nsfe.getMessage());
175        }
176    }
177    
178    /**
179     * {@inheritDoc}
180     * @return the hash code of a map with no entries
181     */
182    public int hashCode() {
183        return asMap().hashCode();
184    }
185    
186    /**
187     * {@inheritDoc}
188     * @return true if and only if o is an instance of
189     *  this class or a descendant.
190     */
191    public boolean equals(Object o) {
192        return (o instanceof EmptyRichAnnotation);
193    }
194    
195}