/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.bio; import org.biojava.utils.ChangeEvent; import org.biojava.utils.ChangeForwarder; import org.biojava.utils.ChangeSupport; import org.biojava.utils.ChangeType; import org.biojava.utils.Changeable; /** *
Indicates that an object has an associated annotation.
* *Many BioJava objects will have associated unstructured * data. This should be stored in an Annotation instance. However, the * BioJava object itself will probably not want to extend the * Annotation interface directly, but rather delegate off that * functionality to an Annotation property. The Annotatable interface * indicates that there is an Annotation property. When implementing * Annotatable, you should always create a protected or private field * containing an instance of ChangeForwarder, and register it as a * ChangeListener with the associated Annotation delegate * instance.
* ** public class Foo extends AbstractChangeable implements Annotatable { * private Annotation ann; // the associated annotation delegate * protected ChangeForwarder annFor; // the event forwarder * * public Foo() { * // make the ann delegate * ann = new SimpleAnnotation(); * // construct the forwarder so that it emits Annotatable.ANNOTATION ChangeEvents * // for the Annotation.PROPERTY events it will listen for * annFor = new ChangeForwarder.Retyper(this, getChangesupport( Annotatable.ANNOTATION ), * Annotatable.ANNOTATION ); * // connect the forwarder so it listens for Annotation.PROPERTY events * ann.addChangeListener( annFor, Annotation.PROPERTY ); * } * * public Annotation getAnnotation() { * return ann; * } * } ** Check if BioJava classes and interfaces extend Annotatable. This * will tell you if you should look for associated annotation. * * If an object implements Annotatable, it may well propagate * ChangeEvent notifications from the associated Annotation. You may * need to track these to maintain the state of your applications. * * Be careful to hook up the appropriate event forwarders. * * The getAnnotation() method can be implemented lazily * (instantiate the Annotation instance and event forwarders when the first * request comes in). It can also be implemented by returning throw-away * immutable Annotation instances that are built from scratch each time. * @author Matthew Pocock * @author Keith James (docs). * @author Kalle N�slund (docs) * @see org.biojavax.RichAnnotatable * @since 1.0 */ public interface Annotatable extends Changeable { /** * Signals that the associated Annotation has altered in some way. The * chainedEvent property should refer back to the event fired by the * Annotation object. */ public static final ChangeType ANNOTATION = new ChangeType( "the associated annotation has changed", "org.biojava.bio.Annotatable", "ANNOTATION" ); /** * Should return the associated annotation object. * * @return an Annotation object, never null */ Annotation getAnnotation(); /** *
A helper class so that you don't have to worry about * forwarding events from the Annotation object to the Annotatable * one.
* *Once a listener is added to your Annotatable that is * interested in ANNOTATION events, then instantiate one of these * and add it as a listener to the annotation object. It will * forward the events to your listeners and translate them * accordingly.
This will ease the pain of letting your Annotatable tell its * listeners about changes in the Annotation. * * @author Matthew Pocock * * @deprecated use *new ChangeForwarder.Retyper(source, cs, Annotation.PROPERTY)
* instead
*/
static class AnnotationForwarder extends ChangeForwarder {
/**
* Create a new AnnotationForwarder that will forward events for a source
* using a change support.
*
* @param source the Object to forward events on behalf of
* @param cs the change support that manages listeners
*/
public AnnotationForwarder(Object source, ChangeSupport cs) {
super(source, cs);
}
protected ChangeEvent generateEvent(ChangeEvent ce) {
ChangeType ct = ce.getType();
if(ct == Annotation.PROPERTY) {
return new ChangeEvent(
getSource(),
ANNOTATION,
ct
);
}
return null;
}
}
}