All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.biojavax.SimpleRichAnnotation Maven / Gradle / Ivy

There is a newer version: 1.9.7
Show newest version
/*
 *                    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/
 *
 */

/*
 * SimpleRichAnnotation.java
 *
 * Created on July 29, 2005, 10:30 AM
 */

package org.biojavax;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.biojava.bio.Annotatable;
import org.biojava.ontology.Term;
import org.biojava.utils.AbstractChangeable;
import org.biojava.utils.ChangeEvent;
import org.biojava.utils.ChangeSupport;
import org.biojava.utils.ChangeVetoException;
import org.biojavax.ontology.ComparableTerm;

/**
 * Simple annotation wrapper. All non-Note annotations get a rank of zero.
 * @author Richard Holland
 * @author George Waldon - adapted note change firing
 * @since 1.5
 */
public class SimpleRichAnnotation extends AbstractChangeable implements RichAnnotation {
    
    private Set notes = new TreeSet(); // Keeps them ordered by rank then term
    
    /** Creates a new, empty instance of SimpleRichAnnotation */
    public SimpleRichAnnotation() {}
    
    /**
     * {@inheritDoc}
     */
    public void clear() throws ChangeVetoException{ 
    	// Use copy of list in order to prevent concurrent modifications.
    	// Fix for bug #2258.
        for(Iterator i = (new ArrayList(this.notes)).iterator(); i.hasNext(); ){
            this.removeNote(i.next());
        }
    }
    
    /**
     * {@inheritDoc}
     * The map is a copy of the internal structure. It is a map of 
     * ComparableTerms to Strings corresponding
     * to the Term and Value of the Notes in the annotation.
     */
    public Map asMap() {
        Map m = new TreeMap();
        for (Iterator i = this.notes.iterator(); i.hasNext(); ) {
            Note n = i.next();
            m.put(n.getTerm(), n.getValue());
        }
        return m;
    }
    
    /**
     * {@inheritDoc}
     * In case the note was already here, a call to ChangeEvent.getPrevious()
     * in the firePostChangeEvent method will return a copy of the original note.
     */
    public void addNote(Note note) throws ChangeVetoException {
        if (note==null) throw new IllegalArgumentException("Note cannot be null");
        if(!this.hasListeners(Annotatable.ANNOTATION)) {
            this.notes.add(note);
        } else {
            ChangeEvent ce = new ChangeEvent(
                    this,
                    Annotatable.ANNOTATION,
                    note,
                    null
                    );
            ChangeSupport cs = this.getChangeSupport(Annotatable.ANNOTATION);
            synchronized(cs) {
                cs.firePreChangeEvent(ce);
                boolean change = this.notes.add(note);
                if(!change) {
                    Note current = null;
                    Iterator it = notes.iterator();
                    while(it.hasNext()) {
                        current = it.next();
                        if(note.equals(current))
                            break;
                    }
                    Note clone = new SimpleNote(current.getTerm(),current.getValue(),current.getRank());
                    current.setValue(note.getValue()); //will fire Note.VALUE
                    ce = new ChangeEvent(
                    this,
                    Annotatable.ANNOTATION,
                    current,
                    clone
                    );
                }
                cs.firePostChangeEvent(ce);
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public boolean contains(Note note) { return this.notes.contains(note); }
    
    /**
     * {@inheritDoc}
     * @deprecated 
     */
    public boolean containsProperty(Object key) { 
        if (key instanceof Term) key = RichObjectFactory.getDefaultOntology().getOrImportTerm((Term)key);
        else key = RichObjectFactory.getDefaultOntology().getOrCreateTerm(key.toString());
        for(Iterator i = notes.iterator(); i.hasNext();){
            Note n = i.next();
            if(n.getTerm().equals(key)) return true;
        }
    	return false; 
    }
    
    /**
     * {@inheritDoc}
     */
    public Note getNote(Note note) throws NoSuchElementException {
        if (note==null) throw new IllegalArgumentException("Note cannot be null");
        for (Iterator i = this.notes.iterator(); i.hasNext(); ) {
            Note n = i.next();
            if (note.equals(n)) return n;
        }
        throw new NoSuchElementException("No such property: "+note.getTerm()+", rank "+note.getRank());
    }
    
    /**
     * {@inheritDoc}
     * Strictly it will return the first Note which matches the 
     * key (or a Term made with a String key)..
     * @see #getProperties(Object key)
     * @deprecated 
     */
    public Object getProperty(Object key) throws NoSuchElementException { 
        if (key instanceof Term) key = RichObjectFactory.getDefaultOntology().getOrImportTerm((Term)key);
        else key = RichObjectFactory.getDefaultOntology().getOrCreateTerm(key.toString());
        for(Iterator i = notes.iterator(); i.hasNext();){
            Note n = i.next();
            if (n.getTerm().equals(key)) return n.getValue();
        }
        throw new NoSuchElementException("No such property: "+key); 
  	}
    
    /**
     * {@inheritDoc}
     * Strictly it will return all Notes which match the 
     * key (or a Term made with a String key)..
     * @deprecated 
     */
    public Note[] getProperties(Object key){
        if (key instanceof Term) key = RichObjectFactory.getDefaultOntology().getOrImportTerm((Term)key);
        else key = RichObjectFactory.getDefaultOntology().getOrCreateTerm(key.toString());
        List l = new LinkedList();
        for(Iterator i = notes.iterator(); i.hasNext();){
            Note n = i.next();
            if (n.getTerm().equals(key)) l.add(n);
        }
        Collections.sort(l);
        Note[] na = new Note[l.size()];
        l.toArray(na);
        return na;
    }
    
    /**
     * {@inheritDoc}
     */
    public Set keys() { return this.asMap().keySet(); }
    
    /**
     * {@inheritDoc}
     * In case the note is not found, a call to ChangeEvent.getPrevious()
     * in the firePostChangeEvent method will return null.
     */
    public void removeNote(Note note) throws ChangeVetoException {
        if (note==null) throw new IllegalArgumentException("Note cannot be null");
        if(!this.hasListeners(Annotatable.ANNOTATION)) {
            this.notes.remove(note);
        } else {
            ChangeEvent ce = new ChangeEvent(
                    this,
                    Annotatable.ANNOTATION,
                    null,
                    note
                    );
            ChangeSupport cs = this.getChangeSupport(Annotatable.ANNOTATION);
            synchronized(cs) {
                cs.firePreChangeEvent(ce);
                boolean removed = this.notes.remove(note);
                if(!removed)
                    ce = new ChangeEvent(
                    this,
                    Annotatable.ANNOTATION,
                    null,
                    null
                    );
                cs.firePostChangeEvent(ce);
            }
        }
    }
    
    /**
     * {@inheritDoc}
     * Strictly it will remove the first Note which matches the 
     * key (or a Term made with a String key)..
     * @deprecated 
     */
    public void removeProperty(Object key) throws NoSuchElementException, ChangeVetoException { 
        if (key instanceof Term) key = RichObjectFactory.getDefaultOntology().getOrImportTerm((Term)key);
        else key = RichObjectFactory.getDefaultOntology().getOrCreateTerm(key.toString());
        for(Iterator i = notes.iterator(); i.hasNext();){
            Note n = i.next();
            if (n.getTerm().equals(key)) {
            	this.removeNote(n); 
            	return;
            }
        }
        throw new NoSuchElementException("No such property: "+key); 
    }
    
    /**
     * {@inheritDoc}
     * @deprecated 
     */
    public void setProperty(Object key, Object value) throws IllegalArgumentException, ChangeVetoException {
        if(key == null) throw new IllegalArgumentException("Property keys cannot be null");
        if (key instanceof Term) key = RichObjectFactory.getDefaultOntology().getOrImportTerm((Term)key);
        else key = RichObjectFactory.getDefaultOntology().getOrCreateTerm(key.toString());
        this.addNote(new SimpleNote((ComparableTerm)key, (String)(value==null?value:value.toString()), 0));
    }
    
    /**
     * {@inheritDoc}
     * Warning this method gives access to the original 
     * Collection not a copy. This is required by Hibernate. If you
     * modify the object directly the behaviour may be unpredictable.
     */
    public Set getNoteSet() {  return this.notes; } // original for Hibernate
    
    /**
     * {@inheritDoc}
     * Warning this method gives access to the original 
     * Collection not a copy. This is required by Hibernate. If you
     * modify the object directly the behaviour may be unpredictable.
     */
    public void setNoteSet(Set notes) throws ChangeVetoException { this.notes = notes; } // original for Hibernate
    
    /**
     * {@inheritDoc}
     * Form: list of "[note]" values separated by commas
     */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        for (Iterator i = this.notes.iterator(); i.hasNext(); ) {
            sb.append("[");
            sb.append(i.next());
            sb.append("]");
            if (i.hasNext()) sb.append(",");
        }
        return sb.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy