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 022package org.biojava.directory; 023 024import java.util.Iterator; 025import java.util.List; 026import java.util.Map; 027 028import org.biojava.bio.BioException; 029import org.biojava.bio.seq.db.SequenceDBLite; 030import org.biojava.utils.ClassTools; 031import org.biojava.utils.Services; 032 033/** 034 * <p><code>Registry</code> is a factory which gets implementations of 035 * the BioJava <code>SequenceDBLite</code> interface. This is the 036 * point of entry for OBDA access.</p> 037 * 038 * @author Brian Gilman 039 * @author Thomas Down 040 * @author Keith James 041 * 042 * @version $Revision$ 043 */ 044public class Registry { 045 046 /** 047 * Registry Configuration instance 048 */ 049 private RegistryConfiguration regConfig = null; 050 051 /** 052 * Creates a new OBDA <code>Registry</code> with the specified 053 * configuration. 054 * 055 * @param regConfig a <code>RegistryConfiguration</code>. 056 */ 057 public Registry(RegistryConfiguration regConfig) { 058 this.regConfig = regConfig; 059 } 060 061 /** 062 * <code>getDatabase</code> retrieves a database instance known by 063 * a name <code>String</code>. 064 * 065 * @param dbName a <code>String</code> database name. 066 * 067 * @return a <code>SequenceDBLite</code>. 068 * 069 * @exception RegistryException if the registry does not contain a 070 * configuration for the specified name. 071 * @exception BioException if the provider fails. 072 */ 073 public SequenceDBLite getDatabase(String dbName) 074 throws RegistryException, BioException { 075 076 String providerName = ""; 077 078 List dbConfigs = 079 (List) getRegistryConfiguration().getConfiguration().get(dbName); 080 081 if (dbConfigs == null) { 082 throw new RegistryException("Failed to find a configuration" 083 + " for database: " 084 + dbName); 085 } 086 087 for (Iterator ci = dbConfigs.iterator(); ci.hasNext();) { 088 Map dbConfig = (Map) ci.next(); 089 providerName = (String) dbConfig.get("protocol"); 090 091 SequenceDBLite db = null; 092 try { 093 db = getProvider(providerName).getSequenceDB(dbConfig); 094 } catch (RegistryException re) { 095 // We allow RegistryExceptions to cause a fallback to 096 // an alternative provider in the same config 097 continue; 098 } 099 catch (Exception e) { 100 // But more serious exceptions cause a failure 101 throw new RegistryException("Failed to configure database " 102 + dbName); 103 } 104 105 if (db != null) 106 return db; 107 } 108 109 throw new RegistryException("Failed to find a configuration" 110 + " for database: " 111 + dbName); 112 } 113 114 private SequenceDBProvider getProvider(String providerName) 115 throws RegistryException { 116 try { 117 ClassLoader loader = ClassTools.getClassLoader(this); 118 Iterator implNames = 119 Services.getImplementationNames(SequenceDBProvider.class, loader).iterator(); 120 121 while (implNames.hasNext()) { 122 String className = (String) implNames.next(); 123 try { 124 Class clazz = loader.loadClass(className); 125 SequenceDBProvider seqDB = 126 (SequenceDBProvider) clazz.newInstance(); 127 if (seqDB.getName().equals(providerName)) { 128 return seqDB; 129 } 130 } catch (ClassNotFoundException ce) { 131 throw new RegistryException( 132 "Could not find class: " + className + 133 " for service provider " + providerName, ce 134 ); 135 } 136 } 137 138 throw new ProviderNotFoundException("No such provider exists: " 139 + providerName); 140 } catch (Exception e) { 141 throw new RegistryException("Error accessing" 142 + " SequenceDBProvider services",e); 143 } 144 } 145 146 /** 147 * <code>getRegistryConfiguration</code> returns the configuration 148 * of the registry. 149 * 150 * @return a <code>RegistryConfiguration</code>. 151 */ 152 public RegistryConfiguration getRegistryConfiguration() { 153 return this.regConfig; 154 } 155}