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.Collections; 025import java.util.Map; 026 027import org.biojava.utils.OverlayMap; 028 029/** 030 * <p>The BioDirectory Registry is a simple system for specifying 031 * where to find services which provide sequence databases. A client 032 * should look at the following places in order to find this file:</p> 033 * 034 * <pre> 035 * $HOME/.bioinformatics/seqdatabase.ini 036 * /etc/bioinformatics/seqdatabase.ini 037 * http://www.open-bio.org/registry/seqdatabase.ini 038 * </pre> 039 * 040 * <p>The file is a simple stanza format</p> 041 * 042 * <pre> 043 * [database-name] 044 * tag=value 045 * tag=value 046 * 047 * [database-name] 048 * tag=value 049 * tag=value 050 * </pre> 051 * 052 * <p>where each stanza starts with the declaration of the database 053 * being in square brackets and following that one line tag=value tag 054 * value formats.</p> 055 * 056 * <p>Database-name stanzas can be repeated, in which case the client 057 * should try each service in turn (starting at the first one).</p> 058 * 059 * <p>The options under each stanza must have two non-optional 060 * tag=value lines being</p> 061 * 062 * <pre> 063 * protocol=<protocol-type> 064 * location=<location-string> 065 * </pre> 066 * 067 * <p>'protocol' currently can be one of</p> 068 * 069 * <ul> 070 * <li>flat</li> 071 * <li>biofetch</li> 072 * <li>biosql</li> 073 * </ul> 074 * 075 * <p>'location' is a string specific to the protocol. Any number of 076 * additional tag values are allowed in the stanza which should be 077 * passed to the appropiate constructor of the protocol to 078 * interpret. Some protocols might insist on other mandatory tags.</p> 079 * 080 * @author Brian Gilman 081 * @author Keith James 082 * @author Matthew Pocock 083 * @version $Revision$ 084 */ 085public interface RegistryConfiguration { 086 /** 087 * <code>getConfiguration</code> returns a mapping of registry 088 * database names to collections of tag-value pairs. 089 * 090 * @return a <code>Map</code>. 091 * 092 * @exception RegistryException if an error occurs. 093 */ 094 public Map getConfiguration() throws RegistryException; 095 096 /** 097 * <code>getConfigLocator</code> returns a locator for the 098 * configuration. 099 * 100 * @return a <code>String</code>. 101 */ 102 public String getConfigLocator(); 103 104 /** 105 * A simple implementation of RegistryConfiguration backed by a Map. 106 * 107 * @author Brian Gilman 108 * @author Matthew Pocock 109 */ 110 public static class Impl implements RegistryConfiguration { 111 private String configFileLocation = null; 112 private Map config = null; 113 114 public Impl(String configFileLocation, Map config){ 115 this.configFileLocation = configFileLocation; 116 this.config = config; 117 } 118 119 public Map getConfiguration() { 120 return config; 121 } 122 123 public String getConfigLocator() { 124 return configFileLocation; 125 } 126 } 127 128 /** 129 * A RegistryConfiguration that allows you to treat other 130 * configurations as providing important or default configuration 131 * information. 132 * 133 * @author Matthew Pocock 134 */ 135 public static class Composite 136 implements RegistryConfiguration { 137 private String configLocator; 138 private Map config; 139 140 public Composite() { 141 } 142 143 public Map getConfiguration() { 144 if(config == null) { 145 return Collections.EMPTY_MAP; 146 } else { 147 return config; 148 } 149 } 150 151 public String getConfigLocator() { 152 return configLocator; 153 } 154 155 /** 156 * Add a configuration as the most authoritative place to look. 157 * During future lookups with this context, values in newConfig 158 * will take precedence over values in the previously existing 159 * configuration. 160 * 161 * @param newConfig the RegistryConfiguration to add as most 162 * important 163 */ 164 public void addTopConfig(RegistryConfiguration newConfig) 165 throws RegistryException { 166 Map cfg = newConfig.getConfiguration(); 167 if(config == null) { 168 config = cfg; 169 configLocator = newConfig.getConfigLocator(); 170 } else { 171 config = new OverlayMap(config, cfg); 172 configLocator = newConfig.getConfigLocator() + "::" + configLocator; 173 } 174 } 175 176 /** 177 * Add a configuration as the most default place to look. During 178 * future lookups with this context, values in newConfig will be 179 * used as default values only if the lookup would return nothing 180 * in the previously existing configuration. 181 * 182 * @param newConfig the RegistryConfiguration to add as the 183 * default 184 */ 185 public void addBottomConfig(RegistryConfiguration newConfig) 186 throws RegistryException { 187 Map cfg = newConfig.getConfiguration(); 188 if(config == null) { 189 config = cfg; 190 configLocator = newConfig.getConfigLocator(); 191 } else { 192 config = new OverlayMap(cfg, config); 193 configLocator = configLocator + "::" + newConfig.getConfigLocator(); 194 } 195 } 196 } 197}