/** * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * * Created on Aug 31, 2011 * Created by Andreas Prlic * * @since 3.0.2 */ package org.biojava.nbio.structure.domain; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; import org.biojava.nbio.structure.ResidueRange; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.SubstructureIdentifier; import org.biojava.nbio.structure.align.client.JFatCatClient; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.align.util.URLConnectionTools; import org.biojava.nbio.structure.scop.server.XMLUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** A class that provided PDP assignments that are loaded from a remote web server * * @author Andreas Prlic * */ public class RemotePDPProvider extends SerializableCache<String,SortedSet<String>> implements PDPProvider{ private static final Logger logger = LoggerFactory.getLogger(RemotePDPProvider.class); public static final String DEFAULT_SERVER = "http://source.rcsb.org/jfatcatserver/domains/"; String server = DEFAULT_SERVER; private static String CACHE_FILE_NAME = "remotepdpdomaindefs.ser"; public static void main(String[] args) throws IOException, StructureException{ RemotePDPProvider me = new RemotePDPProvider(true); //System.out.println(scop.getByCategory(ScopCategory.Superfamily)); SortedSet<String> pdpdomains = me.getPDPDomainNamesForPDB("4HHB"); System.out.println(pdpdomains); AtomCache cache = new AtomCache(); Structure s = me.getDomain(pdpdomains.first(), cache); System.out.println(s); me.flushCache(); } public RemotePDPProvider(){ // equivalent to this(false) but without IOException super(CACHE_FILE_NAME); disableCache(); } /** * * @param useCache * @throws IOException */ public RemotePDPProvider(boolean useCache) throws IOException { super(CACHE_FILE_NAME); if ( ! useCache) { disableCache(); //else if ( serializedCache.keySet().size() < 10000){ } else { // make sure we always have the latest assignments... loadRepresentativeDomains(); } } /** get the ranges of representative domains from the centralized server * @throws IOException if the server cannot be reached */ private void loadRepresentativeDomains() throws IOException { AssignmentXMLSerializer results = null; try { URL u = new URL(server + "getRepresentativePDPDomains"); logger.info("Fetching {}",u); InputStream response = URLConnectionTools.getInputStream(u); String xml = JFatCatClient.convertStreamToString(response); results = AssignmentXMLSerializer.fromXML(xml); Map<String,String> data = results.getAssignments(); logger.info("got {} domain ranges for PDP domains from server.",data.size()); for (String key: data.keySet()){ String range = data.get(key); // work around list in results; String[] spl = range.split(","); SortedSet<String> value = new TreeSet<String>(); for (String s : spl){ value.add(s); } serializedCache.put(key, value); } } catch (MalformedURLException e){ logger.error("Malformed PDP server: "+server,e); throw new IllegalArgumentException("Invalid Server: "+server, e); } } public String getServer() { return server; } public void setServer(String server) { this.server = server; } /** * Get the structure for a particular PDP domain * @param pdpDomainName PDP identifier, e.g. "PDP:4HHBAa" * @param cache AtomCache, responsible for fetching and storing the coordinates * @return Structure representing the PDP domain * @throws IOException if the server cannot be reached * @throws StructureException For errors parsing the structure */ @Override public Structure getDomain(String pdpDomainName, AtomCache cache) throws IOException, StructureException { return cache.getStructure(getPDPDomain(pdpDomainName)); } /** * Get a StructureIdentifier representing the specified PDP domain. * * @param pdpDomainName PDP domain name * @return a PDPDomain representing this domain name * @throws IOException if the server cannot be reached */ @Override public PDPDomain getPDPDomain(String pdpDomainName) throws IOException{ SortedSet<String> domainRanges = null; if ( serializedCache != null){ if ( serializedCache.containsKey(pdpDomainName)){ domainRanges= serializedCache.get(pdpDomainName); } } boolean shouldRequestDomainRanges = checkDomainRanges(domainRanges); try { if (shouldRequestDomainRanges){ URL u = new URL(server + "getPDPDomain?pdpId="+pdpDomainName); logger.info("Fetching {}",u); InputStream response = URLConnectionTools.getInputStream(u); String xml = JFatCatClient.convertStreamToString(response); domainRanges = XMLUtil.getDomainRangesFromXML(xml); if ( domainRanges != null) cache(pdpDomainName,domainRanges); } } catch (MalformedURLException e){ logger.error("Problem generating PDP request URL for "+pdpDomainName,e); throw new IllegalArgumentException("Invalid PDP name: "+pdpDomainName, e); } String pdbId = null; List<ResidueRange> ranges = new ArrayList<ResidueRange>(); for(String domainRange : domainRanges) { SubstructureIdentifier strucId = new SubstructureIdentifier(domainRange); if(pdbId == null) { pdbId = strucId.getPdbId(); } else if(!pdbId.equals(strucId.getPdbId())) { // should never happen with correct server implementation throw new RuntimeException("Don't know how to take the union of domains from multiple PDB IDs."); } ranges.addAll(strucId.getResidueRanges()); } return new PDPDomain(pdpDomainName,ranges); } /** returns true if client should fetch domain definitions from server * * @param domainRanges * @return */ private boolean checkDomainRanges(SortedSet<String> domainRanges) { if ( (domainRanges == null) || (domainRanges.size() == 0)){ return true; } for ( String d : domainRanges){ //System.out.println("domainRange: >" + d +"< " + d.length()); if ( (d != null) && (d.length() >0)){ return false; } } return true; } /** * Get a list of all PDP domains for a given PDB entry * @param pdbId PDB ID * @return Set of domain names, e.g. "PDP:4HHBAa" * @throws IOException if the server cannot be reached */ @Override public SortedSet<String> getPDPDomainNamesForPDB(String pdbId) throws IOException{ SortedSet<String> results = null; try { URL u = new URL(server + "getPDPDomainNamesForPDB?pdbId="+pdbId); logger.info("Fetching {}",u); InputStream response = URLConnectionTools.getInputStream(u); String xml = JFatCatClient.convertStreamToString(response); results = XMLUtil.getDomainRangesFromXML(xml); } catch (MalformedURLException e){ logger.error("Problem generating PDP request URL for "+pdbId,e); throw new IllegalArgumentException("Invalid PDB name: "+pdbId, e); } return results; } }