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 * Created on Aug 31, 2011 021 * Created by Andreas Prlic 022 * 023 * @since 3.0.2 024 */ 025package org.biojava.nbio.structure.domain; 026 027import java.io.IOException; 028import java.io.InputStream; 029import java.net.MalformedURLException; 030import java.net.URL; 031import java.util.ArrayList; 032import java.util.List; 033import java.util.Map; 034import java.util.SortedSet; 035import java.util.TreeSet; 036 037import org.biojava.nbio.structure.ResidueRange; 038import org.biojava.nbio.structure.Structure; 039import org.biojava.nbio.structure.StructureException; 040import org.biojava.nbio.structure.SubstructureIdentifier; 041import org.biojava.nbio.structure.align.client.JFatCatClient; 042import org.biojava.nbio.structure.align.util.AtomCache; 043import org.biojava.nbio.structure.align.util.URLConnectionTools; 044import org.biojava.nbio.structure.scop.server.XMLUtil; 045import org.slf4j.Logger; 046import org.slf4j.LoggerFactory; 047 048 049/** A class that provided PDP assignments that are loaded from a remote web server 050 * 051 * @author Andreas Prlic 052 * 053 */ 054public class RemotePDPProvider extends SerializableCache<String,SortedSet<String>> implements PDPProvider{ 055 056 private static final Logger logger = LoggerFactory.getLogger(RemotePDPProvider.class); 057 058 public static final String DEFAULT_SERVER = "http://source.rcsb.org/jfatcatserver/domains/"; 059 060 String server = DEFAULT_SERVER; 061 062 private static String CACHE_FILE_NAME = "remotepdpdomaindefs.ser"; 063 064 065 public static void main(String[] args) throws IOException, StructureException{ 066 RemotePDPProvider me = new RemotePDPProvider(true); 067 068 //System.out.println(scop.getByCategory(ScopCategory.Superfamily)); 069 SortedSet<String> pdpdomains = me.getPDPDomainNamesForPDB("4HHB"); 070 System.out.println(pdpdomains); 071 072 AtomCache cache = new AtomCache(); 073 Structure s = me.getDomain(pdpdomains.first(), cache); 074 System.out.println(s); 075 076 me.flushCache(); 077 078 } 079 080 081 public RemotePDPProvider(){ 082 // equivalent to this(false) but without IOException 083 super(CACHE_FILE_NAME); 084 disableCache(); 085 } 086 087 088 /** 089 * 090 * @param useCache 091 * @throws IOException 092 */ 093 public RemotePDPProvider(boolean useCache) throws IOException { 094 095 super(CACHE_FILE_NAME); 096 097 if ( ! useCache) { 098 disableCache(); 099 //else if ( serializedCache.keySet().size() < 10000){ 100 } else { 101 // make sure we always have the latest assignments... 102 loadRepresentativeDomains(); 103 } 104 105 } 106 107 108 109 /** get the ranges of representative domains from the centralized server 110 * @throws IOException if the server cannot be reached 111 */ 112 private void loadRepresentativeDomains() throws IOException { 113 114 AssignmentXMLSerializer results = null; 115 try { 116 URL u = new URL(server + "getRepresentativePDPDomains"); 117 logger.info("Fetching {}",u); 118 InputStream response = URLConnectionTools.getInputStream(u); 119 String xml = JFatCatClient.convertStreamToString(response); 120 results = AssignmentXMLSerializer.fromXML(xml); 121 122 Map<String,String> data = results.getAssignments(); 123 logger.info("got {} domain ranges for PDP domains from server.",data.size()); 124 for (String key: data.keySet()){ 125 String range = data.get(key); 126 127 // work around list in results; 128 129 String[] spl = range.split(","); 130 SortedSet<String> value = new TreeSet<String>(); 131 132 for (String s : spl){ 133 value.add(s); 134 135 } 136 serializedCache.put(key, value); 137 } 138 139 } catch (MalformedURLException e){ 140 logger.error("Malformed PDP server: "+server,e); 141 throw new IllegalArgumentException("Invalid Server: "+server, e); 142 } 143 } 144 145 146 public String getServer() { 147 return server; 148 } 149 150 public void setServer(String server) { 151 this.server = server; 152 } 153 154 /** 155 * Get the structure for a particular PDP domain 156 * @param pdpDomainName PDP identifier, e.g. "PDP:4HHBAa" 157 * @param cache AtomCache, responsible for fetching and storing the coordinates 158 * @return Structure representing the PDP domain 159 * @throws IOException if the server cannot be reached 160 * @throws StructureException For errors parsing the structure 161 */ 162 @Override 163 public Structure getDomain(String pdpDomainName, AtomCache cache) throws IOException, StructureException { 164 return cache.getStructure(getPDPDomain(pdpDomainName)); 165 } 166 167 /** 168 * Get a StructureIdentifier representing the specified PDP domain. 169 * 170 * @param pdpDomainName PDP domain name 171 * @return a PDPDomain representing this domain name 172 * @throws IOException if the server cannot be reached 173 */ 174 @Override 175 public PDPDomain getPDPDomain(String pdpDomainName) throws IOException{ 176 SortedSet<String> domainRanges = null; 177 if ( serializedCache != null){ 178 if ( serializedCache.containsKey(pdpDomainName)){ 179 domainRanges= serializedCache.get(pdpDomainName); 180 181 } 182 } 183 184 185 boolean shouldRequestDomainRanges = checkDomainRanges(domainRanges); 186 187 try { 188 if (shouldRequestDomainRanges){ 189 URL u = new URL(server + "getPDPDomain?pdpId="+pdpDomainName); 190 logger.info("Fetching {}",u); 191 InputStream response = URLConnectionTools.getInputStream(u); 192 String xml = JFatCatClient.convertStreamToString(response); 193 domainRanges = XMLUtil.getDomainRangesFromXML(xml); 194 if ( domainRanges != null) 195 cache(pdpDomainName,domainRanges); 196 } 197 } catch (MalformedURLException e){ 198 logger.error("Problem generating PDP request URL for "+pdpDomainName,e); 199 throw new IllegalArgumentException("Invalid PDP name: "+pdpDomainName, e); 200 } 201 202 String pdbId = null; 203 List<ResidueRange> ranges = new ArrayList<ResidueRange>(); 204 for(String domainRange : domainRanges) { 205 SubstructureIdentifier strucId = new SubstructureIdentifier(domainRange); 206 if(pdbId == null) { 207 pdbId = strucId.getPdbId(); 208 } else if(!pdbId.equals(strucId.getPdbId())) { 209 // should never happen with correct server implementation 210 throw new RuntimeException("Don't know how to take the union of domains from multiple PDB IDs."); 211 } 212 213 ranges.addAll(strucId.getResidueRanges()); 214 } 215 return new PDPDomain(pdpDomainName,ranges); 216 } 217 218 /** returns true if client should fetch domain definitions from server 219 * 220 * @param domainRanges 221 * @return 222 */ 223 private boolean checkDomainRanges(SortedSet<String> domainRanges) { 224 225 if ( (domainRanges == null) || (domainRanges.size() == 0)){ 226 return true; 227 } 228 229 for ( String d : domainRanges){ 230 //System.out.println("domainRange: >" + d +"< " + d.length()); 231 if ( (d != null) && (d.length() >0)){ 232 return false; 233 } 234 } 235 236 return true; 237 } 238 239 /** 240 * Get a list of all PDP domains for a given PDB entry 241 * @param pdbId PDB ID 242 * @return Set of domain names, e.g. "PDP:4HHBAa" 243 * @throws IOException if the server cannot be reached 244 */ 245 @Override 246 public SortedSet<String> getPDPDomainNamesForPDB(String pdbId) throws IOException{ 247 SortedSet<String> results = null; 248 try { 249 URL u = new URL(server + "getPDPDomainNamesForPDB?pdbId="+pdbId); 250 logger.info("Fetching {}",u); 251 InputStream response = URLConnectionTools.getInputStream(u); 252 String xml = JFatCatClient.convertStreamToString(response); 253 results = XMLUtil.getDomainRangesFromXML(xml); 254 255 } catch (MalformedURLException e){ 256 logger.error("Problem generating PDP request URL for "+pdbId,e); 257 throw new IllegalArgumentException("Invalid PDB name: "+pdbId, e); 258 } 259 return results; 260 } 261}