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}