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
022
023package org.biojava.bio;
024
025import java.util.Map;
026import java.util.NoSuchElementException;
027import java.util.Set;
028
029import org.biojava.utils.ChangeType;
030import org.biojava.utils.ChangeVetoException;
031import org.biojava.utils.Changeable;
032
033/**
034 * <p>
035 * Arbitrary annotation associated with one or more objects.
036 * </p>
037 *
038 * <p>
039 * Biological information often does not fit design patterns very well, and can
040 * be a jumble of facts and relationships. Annotation objects provide a standard
041 * way for you to store this mess as a property of an object.
042 * </p>
043 *
044 * <p>
045 * Annotations may contain keys that have Annotations as values. In this way,
046 * annotations can be shared among multiple Annotatable objects, and you can
047 * represent semi-structured data.
048 * </p>
049 *
050 * <p>
051 * It is perfectly possible to wrap up almost any tree-like or flat data
052 * structure as Annotation.
053 * </p>
054 * Other than when using the constructor, you should be able to
055 * interact with nearly all Annotation implementations via this API.
056 *
057 * @author Matthew Pocock
058 * @author Thomas Down
059 * @see org.biojavax.RichAnnotation
060 *
061 *
062 * @since 1.0
063 */
064public interface Annotation extends Changeable {
065  /**
066   * This type symbolizes that one or more properties have changed.
067   */
068  public static final ChangeType PROPERTY = new ChangeType(
069    "Properties have altered",
070    "org.biojava.bio.Annotation",
071    "PROPERTY"
072  );
073  
074  /**
075   * <p>
076   * Retrieve the value of a property by key.
077   * </p>
078   *
079   * <p>
080   * Unlike the Map collections, it will complain if the key does not exist. It
081   * will only return null if the key is defined and has value null.
082   * </p> Normal raw access to the property. For cleverer access, use
083   * methods in AnnotationType.
084   *
085   * @param key  the key of the property to retrieve
086   * @return  the object associated with that key
087   * @throws NoSuchElementException if there is no property with the key
088   *
089   * 
090   */
091  Object getProperty(Object key) throws NoSuchElementException;
092  
093  /**
094   * <p>
095   * Set the value of a property.
096   * </p>
097   *
098   * <p>
099   * This method throws an exception if either properties can not be
100   * added to this object, or that this particular property is immutable or
101   * illegal within the implementation.
102   * </p> Normal raw access to the property. For cleverer access, use
103   * methods in AnnotationType.
104   *
105   * @param key the key object
106   * @param value the new value for this key
107   * @throws IllegalArgumentException if the property <code>key</code> is not
108   *         legal
109   * @throws ChangeVetoException if this annotation object can't be changed, or
110   *         if the change was vetoed. 
111   */
112  void setProperty(Object key, Object value)
113      throws IllegalArgumentException, ChangeVetoException;
114      
115  /**
116   * Delete a property. Normal raw access to the property. For cleverer access, use
117   * methods in AnnotationType.
118   *
119   * @param key the key object
120   * @throws NoSuchElementException if the property doesn't exist
121   * @throws ChangeVetoException if the change is vetoed
122   * @since 1.3
123   * 
124   */
125   
126  public void removeProperty(Object key)
127      throws NoSuchElementException, ChangeVetoException;
128  
129  /**
130   * Returns whether there the property is defined. Normal raw access to the property. For cleverer access, use
131   * methods in AnnotationType.
132   *
133   * @param key the key Object to search for
134   * @return true if this Annotation knows about the key, false otherwise
135   */
136  boolean containsProperty(Object key);
137  
138  /**
139   * Get a set of key objects.
140   *
141   * @return  a Set of key objects
142   */
143  Set keys();
144  
145  /**
146   * Return a map that contains the same key/values as this Annotation.
147   * <p>
148   * If the annotation changes, the map may not reflect this.  The Map
149   * may be unmodifiable.
150   *
151   * @return a Map
152   */
153  Map asMap();
154   
155  /**
156   * <p>
157   * A really useful empty and immutable annotation object.
158   * </p>
159   *
160   * Be careful when stooring Annotation arguments to
161   *  constructors. It is possible that you have been passed EMPTY_ANNOTATION but
162   * that code later on will access this object believing it to be
163   * mutable. For example, the SeqIO factory code clones some
164   * Annotations passed in on Feature.Template instances
165   *
166   * Use this instead of null when you really don't want an object or
167   * an implementation to have annotation even though it should implement
168   * Annotatable.
169   */
170  static final Annotation EMPTY_ANNOTATION = new EmptyAnnotation();
171}
172