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.io;
022
023import org.biojava.nbio.structure.Structure;
024import org.biojava.nbio.structure.StructureException;
025import org.biojava.nbio.structure.align.util.UserConfiguration;
026import org.biojava.nbio.core.util.InputStreamProvider;
027
028import java.io.File;
029import java.io.IOException;
030import java.io.InputStream;
031import java.util.ArrayList;
032import java.util.List;
033
034
035/** The "Sandbox" style of organizing files is  to have a directory structure like below, i.e. the files are organized into
036 * <ul>
037 *      <li>directory with two characters, based on the two middle characters of a PDB ID</li>
038 *      <li>directory of PDB ID</li>
039 *      <li>several files that are available for this PDB ID</li>
040 * </ul>
041 *
042 * <pre>
043a1/2a1v/2a1v.cif.gz
044a1/2a1v/2a1v.dssp.gz
045a1/2a1v/2a1v.pdb-250.jpg.gz
046a1/2a1v/2a1v.pdb-500.jpg.gz
047a1/2a1v/2a1v.pdb-65.jpg.gz
048a1/2a1v/2a1v.pdb-80.jpg.gz
049a1/2a1v/2a1v.pdb1-250.jpg.gz
050a1/2a1v/2a1v.pdb1-500.jpg.gz
051a1/2a1v/2a1v.pdb1-65.jpg.gz
052a1/2a1v/2a1v.pdb1-80.jpg.gz
053a1/2a1v/2a1v.pdb1.gz
054a1/2a1v/2a1v.stride.gz
055a1/2a1v/2a1v.xml.gz
056a1/2a1v/pdb2a1v.ent.gz
057a1/2a1v/r2a1vsf.ent.gz
058a1/2a1w/2a1w-deriv.cif.gz
059a1/2a1w/2a1w-extatom.xml.gz
060a1/2a1w/2a1w-noatom.xml.gz
061a1/2a1w/2a1w.cif.gz
062a1/2a1w/2a1w.dssp.gz
063a1/2a1w/2a1w.pdb-250.jpg.gz
064a1/2a1w/2a1w.pdb-500.jpg.gz
065a1/2a1w/2a1w.pdb-65.jpg.gz
066a1/2a1w/2a1w.pdb-80.jpg.gz
067a1/2a1w/2a1w.pdb1-250.jpg.gz
068a1/2a1w/2a1w.pdb1-500.jpg.gz
069a1/2a1w/2a1w.pdb1-65.jpg.gz
070a1/2a1w/2a1w.pdb1-80.jpg.gz
071a1/2a1w/2a1w.pdb1.gz
072a1/2a1w/2a1w.pdb2-250.jpg.gz
073a1/2a1w/2a1w.pdb2-500.jpg.gz
074a1/2a1w/2a1w.pdb2-65.jpg.gz
075a1/2a1w/2a1w.pdb2-80.jpg.gz
076a1/2a1w/2a1w.pdb2.gz
077a1/2a1w/2a1w.pdb3-250.jpg.gz
078a1/2a1w/2a1w.pdb3-500.jpg.gz
079a1/2a1w/2a1w.pdb3-65.jpg.gz
080a1/2a1w/2a1w.pdb3-80.jpg.gz
081a1/2a1w/2a1w.pdb3.gz
082a1/2a1w/2a1w.pdb4-250.jpg.gz
083a1/2a1w/2a1w.pdb4-500.jpg.gz
084a1/2a1w/2a1w.pdb4-65.jpg.gz
085a1/2a1w/2a1w.pdb4-80.jpg.gz
086a1/2a1w/2a1w.pdb4.gz
087a1/2a1w/2a1w.pdb5-250.jpg.gz
088a1/2a1w/2a1w.pdb5-500.jpg.gz
089a1/2a1w/2a1w.pdb5-65.jpg.gz
090a1/2a1w/2a1w.pdb5-80.jpg.gz
091a1/2a1w/2a1w.pdb5.gz
092a1/2a1w/2a1w.pdb6-250.jpg.gz
093a1/2a1w/2a1w.pdb6-500.jpg.gz
094a1/2a1w/2a1w.pdb6-65.jpg.gz
095a1/2a1w/2a1w.pdb6-80.jpg.gz
096a1/2a1w/2a1w.pdb6.gz
097a1/2a1w/2a1w.stride.gz
098a1/2a1w/2a1w.xml.gz
099a1/2a1w/pdb2a1w.ent.gz
100a1/2a1w/r2a1wsf.ent.gz
101a1/2a1x/2a1x-deriv.cif.gz
102a1/2a1x/2a1x-extatom.xml.gz
103a1/2a1x/2a1x-noatom.xml.gz
104</pre>
105 *
106 *
107 * @author Andreas Prlic
108 *
109 *
110 *@ since3.2
111 */
112public class SandboxStyleStructureProvider implements StructureProvider {
113        FileParsingParameters params ;
114
115        String path;
116        public static final String fileSeparator = System.getProperty("file.separator");
117
118        public SandboxStyleStructureProvider() {
119                params = new FileParsingParameters();
120
121                UserConfiguration config = new UserConfiguration();
122
123                setPath(config.getPdbFilePath());
124        }
125
126        /** directory where to find PDB files */
127        public void setPath(String p){
128
129                path = p ;
130
131                if ( ! (path.endsWith(fileSeparator) ) )
132                        path = path + fileSeparator;
133
134        }
135
136        @Override
137        public Structure getStructureById(String pdbId) throws IOException,StructureException {
138
139
140                if (pdbId == null || pdbId.length()< 4)
141                        throw new StructureException("This does not look like a valid PDB ID! (" + pdbId + ")");
142
143                pdbId = pdbId.toLowerCase();
144
145                String middle = pdbId.substring(1,3).toLowerCase();
146
147                File f = new File(path + fileSeparator + middle + fileSeparator + pdbId  + fileSeparator + "pdb" + pdbId + ".ent.gz");
148
149                if (! f.exists()){
150
151                }
152
153
154                InputStreamProvider isp = new InputStreamProvider();
155
156                InputStream inputStream = isp.getInputStream(f);
157                PDBFileParser pdbpars = new PDBFileParser();
158                pdbpars.setFileParsingParameters(params);
159
160                Structure struc = pdbpars.parsePDBFile(inputStream) ;
161                return struc ;
162
163                // something is wrong with the file!
164                // it probably should be downloaded again...
165                // TODO: add auto-download functionality...
166        }
167
168        @Override
169        public void setFileParsingParameters(FileParsingParameters params) {
170                this.params = params;
171        }
172
173        @Override
174        public FileParsingParameters getFileParsingParameters() {
175                return params;
176        }
177
178        /** Returns a list of all PDB IDs that are available in this installation
179         *
180         * @return a list of PDB IDs
181         */
182        public List<String> getAllPDBIDs() throws IOException{
183
184                File f = new File(path);
185                if ( ! f.isDirectory())
186                        throw new IOException("Path " + path + " is not a directory!");
187
188                String[] dirName = f.list();
189
190                List<String>pdbIds = new ArrayList<String>();
191                for (String dir : dirName) {
192                        File d2= new File(f,dir);
193                        if ( ! d2.isDirectory())
194                                continue;
195
196                        String[] pdbDirs = d2.list();
197                        for (String pdbId : pdbDirs) {
198                                if ( ! pdbIds.contains(pdbId))
199                                        pdbIds.add(pdbId);
200
201                        }
202                }
203
204                return pdbIds;
205        }
206
207}