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 */
021package org.biojava.bio.taxa;
022
023import java.lang.ref.WeakReference;
024import java.util.Iterator;
025import java.util.Map;
026import java.util.Set;
027import java.util.WeakHashMap;
028
029import org.biojava.utils.SmallSet;
030
031/**
032 * <p>An implementation of TaxonFactory that builds a weak in-memory
033 * Taxon tree.</p>
034 *
035 * <p>This implementation holds only weak references to the Taxon
036 * instances it knows about. This means that WeakTaxonFactory may not
037 * be appropriate for situations where you wish to browse the taxon
038 * tree. It does, however, mean that massive taxa can be represented,
039 * by effectively reflecting the currently useful rooted sub-tree in
040 * memory.</p>
041 *
042 * @author Matthew Pocock
043 * @deprecated replaced by classes in {@link org.biojavax.bio.taxa org.biojavax.bio.taxa}
044 */
045public class WeakTaxonFactory implements TaxonFactory {
046  /**
047   * The TaxonFactory that the biojava system should use for storing
048   * the taxonomy used by swissprot and embl as in-memory objects.
049   */
050  public static final WeakTaxonFactory GLOBAL
051    = new WeakTaxonFactory("GLOBAL");
052  
053  private final Taxon root;
054  private final String name;
055  private final Map taxonBySciName = new WeakHashMap();
056  
057  public WeakTaxonFactory(String name) {
058    this.name = name;
059    this.root = createTaxon("ROOT", "");
060  }
061  
062  public Taxon getRoot() {
063    return root;
064  }
065  
066  public String getName() {
067    return name;
068  }
069  
070  public Taxon importTaxon(Taxon taxon) {
071    WeakTaxon can = canonicalize(taxon);
072    if(can == null) {
073      can = new WeakTaxon(taxon.getScientificName(), taxon.getCommonName());
074      
075      for(Iterator i = taxon.getChildren().iterator(); i.hasNext(); ) {
076        Taxon child = (Taxon) i.next();
077        addChild(can, child);
078      }
079      
080      return can;
081    } else {
082      return can;
083    }
084  }
085  
086  public Taxon createTaxon(String scientificName, String commonName) {
087    Taxon taxon = new WeakTaxon(scientificName, commonName);
088    taxonBySciName.put(scientificName, new WeakReference(taxon));
089    return taxon;
090  }
091  
092  public Taxon addChild(Taxon parent, Taxon child) {
093    WeakTaxon sparent = (WeakTaxon) importTaxon(parent);
094    WeakTaxon schild = (WeakTaxon) importTaxon(child);
095    
096    Set children = sparent.getChildrenRaw();
097    if(children == null) {
098      children = new SmallSet();
099      sparent.setChildrenRaw(children);
100    }
101    
102    children.add(schild);
103    schild.setParent(sparent);
104    
105    return schild;
106  }
107  
108  public Taxon removeChild(Taxon parent, Taxon child) {
109    WeakTaxon sparent = canonicalize(parent);
110    WeakTaxon schild = canonicalize(child);
111    
112    if(sparent == null) {
113      throw new IllegalArgumentException("Don't know about parent taxon");
114    }
115    
116    Set children = sparent.getChildrenRaw();
117    if(
118      (schild != null) &&
119      (children != null) &&
120      (children.remove(schild))
121    ) {
122      return schild;
123    } else {
124      return null;
125    }
126  }
127  
128  public Taxon search(Object id) {
129    WeakReference wr = (WeakReference) taxonBySciName.get(id);
130    if(wr != null) {
131      return (Taxon) wr.get();
132    } else {
133      return null;
134    }
135  }
136  
137  private WeakTaxon canonicalize(Taxon taxon) {
138    return (WeakTaxon) search(taxon.getScientificName());
139  }
140}