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.nbio.structure.domain;
022
023import org.biojava.nbio.structure.align.util.URLConnectionTools;
024import org.xml.sax.Attributes;
025import org.xml.sax.InputSource;
026import org.xml.sax.SAXException;
027import org.xml.sax.helpers.DefaultHandler;
028
029import javax.xml.parsers.ParserConfigurationException;
030import javax.xml.parsers.SAXParser;
031import javax.xml.parsers.SAXParserFactory;
032import java.io.*;
033import java.net.MalformedURLException;
034import java.net.URL;
035import java.util.SortedSet;
036import java.util.TreeSet;
037
038
039/**
040 * Class to fetch domains through the RCSB's REST API.
041 *
042 * @author Spencer Bliven
043 *
044 */
045public class PDBDomainProvider implements DomainProvider{
046        public static final String DEFAULT_PDB_HOST = "http://www.rcsb.org";
047        public static final String DEFAULT_PDB_API_URL = DEFAULT_PDB_HOST + "/pdb/rest/";
048
049        private String base;
050        private int cutoff;
051
052        /**
053         */
054        public PDBDomainProvider() {
055                this(DEFAULT_PDB_API_URL,40);
056        }
057        /**
058         * @param base
059         * @param cutoff
060         */
061        public PDBDomainProvider(String base, int cutoff) {
062                this.base = base;
063                this.cutoff = cutoff;
064        }
065
066
067        /**
068         * Gets a list of domain representatives for a given PDB ID.
069         */
070        @Override
071        public SortedSet<String> getDomainNames(String name) {
072                if ( name.length() < 4)
073                        throw new IllegalArgumentException("Can't interpret IDs that are shorter than 4 residues!");
074
075                String url = String.format("%srepresentativeDomains?cluster=%s&structureId=%s",
076                                base, cutoff, name);
077                return requestRepresentativeDomains(url);
078        }
079        /**
080         * Gets a list of all domain representatives
081         */
082        @Override
083        public SortedSet<String> getRepresentativeDomains() {
084                String url = base + "representativeDomains?cluster="+ cutoff;
085                return requestRepresentativeDomains(url);
086        }
087
088        /**
089         * Handles fetching and parsing XML from representativeDomains requests
090         * @param url Eg "http://www.rcsb.org/pdb/rest/representativeDomains"
091         * @return The names of all domain representatives
092         */
093        private SortedSet<String> requestRepresentativeDomains(String url) {
094                try {
095
096                        //System.out.println(url);
097
098                        final SortedSet<String> results = new TreeSet<String>();
099                        DefaultHandler handler = new DefaultHandler() {
100                                @Override
101                                public void startElement(String uri, String localName,String qName,
102                                                Attributes attributes) throws SAXException {
103
104                                        //System.out.println("Start Element :" + qName);
105
106                                        if (qName.equalsIgnoreCase("representative")) {
107                                                String name = attributes.getValue("name");
108                                                results.add(name);
109                                        }
110                                }
111                        };
112                        handleRestRequest(url,handler);
113                        return results;
114                } catch (MalformedURLException e) {
115                        e.printStackTrace();
116                } catch (IOException e) {
117                        e.printStackTrace();
118                } catch (SAXException e) {
119                        e.printStackTrace();
120                } catch (ParserConfigurationException e) {
121                        e.printStackTrace();
122                }
123                return null;
124        }
125        /**
126         * Handles fetching and processing REST requests. The actual XML parsing is handled
127         * by the handler, which is also in charge of storing interesting data.
128         * @param url REST request
129         * @param handler SAX XML parser
130         * @throws SAXException
131         * @throws IOException
132         * @throws ParserConfigurationException
133         */
134        private static void handleRestRequest(String url, DefaultHandler handler) throws SAXException, IOException, ParserConfigurationException {
135                // Fetch XML stream
136                URL u = new URL(url);
137                InputStream response = URLConnectionTools.getInputStream(u);
138                InputSource xml = new InputSource(response);
139
140                // Parse XML
141                SAXParserFactory factory = SAXParserFactory.newInstance();
142                SAXParser saxParser = factory.newSAXParser();
143                saxParser.parse(xml, handler);
144
145        }
146
147
148        //TODO Add methods to access http://www.rcsb.org/pdb/rest/representatives
149
150        public static void main(String[] args){
151                PDBDomainProvider dom = new PDBDomainProvider();
152                String name;
153                name = "2CDG";
154
155                SortedSet<String> domains = dom.getDomainNames(name);
156
157                System.out.println("Domains for "+name+":");
158                for(String s : domains) {
159                        System.out.println(s);
160                }
161
162                SortedSet<String> reprs = dom.getRepresentativeDomains();
163                System.out.format("%nFound %d clusters.%n",reprs.size());
164
165                try {
166                        File outfile  = new File("/Users/blivens/Downloads/representativeDomainsJava.xml");
167                        Writer out = new BufferedWriter(new FileWriter(outfile));
168
169                        for(String repr : reprs) {
170                                out.write(String.format("  <representative name=\"%s\"/>%n", repr));
171                        }
172                        out.close();
173                } catch (IOException e) {
174                        e.printStackTrace();
175                }
176
177        }
178
179
180}