diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipAppendUtil.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipAppendUtil.java deleted file mode 100644 index f82edccb4c..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipAppendUtil.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.logging.Logger; -import java.util.zip.CRC32; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; - -/** -* Singleton helper class to add entries to zip archives. -* @since Feb 8, 2013 -* @author edlunde -* -*/ -public class ZipAppendUtil { - private static final Logger s_logger = Logger.getLogger( ZipAppendUtil.class.getPackage().getName() ); - private boolean busy; - private static ZipAppendUtil s_instance; - - /** - * Get a singleton instance. - * @return - */ - public static ZipAppendUtil getInstance() { - - if (s_instance == null) { - s_instance = new ZipAppendUtil(); - } - return s_instance; - - } - - /** - * Extract contents of sourceArchive to a temporary file, append files to pathWithinArchive, and rezip. - * @param sourceArchive - * @param files - * @param pathWithinArchive - * @return - */ - public boolean addToZipArchive(File sourceArchive, File[] files, String pathWithinArchive){ - if (busy) return false; - - busy = true; - if (files == null) return false; - if(files.length >0){ - try{ - - File tmpZip = File.createTempFile(sourceArchive.getName(), null); - tmpZip.delete(); - if(!sourceArchive.renameTo(tmpZip)){ - s_logger.info("\nDictionary archive is occupied. Reading from a temporary copy instead."); - copyFile(sourceArchive, tmpZip); //Since the chemcomp.zip file cannot be renamed while in use (Win only), copy it to tmpZip - } - byte[] buffer = new byte[1024]; - ZipInputStream zin = new ZipInputStream(new FileInputStream(tmpZip)); - ZipOutputStream out = new ZipOutputStream(new FileOutputStream(sourceArchive)); - for(int i = 0; i < files.length; i++){ - InputStream in = new FileInputStream(files[i]); - ZipEntry entry =new ZipEntry(pathWithinArchive + files[i].getName()); - entry.setSize(files[i].length()); - entry.setTime(files[i].lastModified()); - CRC32 crc32 = new CRC32(); - out.putNextEntry(entry); - for(int read = in.read(buffer); read > -1; read = in.read(buffer)){ - out.write(buffer, 0, read); - crc32.update(buffer,0,read); - } - entry.setCrc(crc32.getValue()); - out.closeEntry(); - in.close(); - } - for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){ - if(!zipEntryMatch(ze.getName(), files, pathWithinArchive)){ - ZipEntry destEntry = new ZipEntry(ze.getName()); - CRC32 crc32 = new CRC32(); - out.putNextEntry(destEntry); - for(int read = zin.read(buffer); read > -1; read = zin.read(buffer)){ - out.write(buffer, 0, read); - crc32.update(buffer,0,read); - } - - destEntry.setCrc(crc32.getValue()); - out.closeEntry(); - } - } - out.close(); - zin.close(); - /* - if(tmpZip.delete()) { - s_logger.info("Successfully deleted temp zip file"); - } - s_logger.info("Wrote downloaded file(s) to "+sourceArchive.getAbsolutePath()); - */ - busy = false; - return true; - }catch(Exception e){ - busy = false; - s_logger.info(e.getMessage()); - return false; - } - } - busy = false; - return false; - } - - /** - * Check for an entry. - * @param zeName - * @param files - * @param path - * @return - */ - private boolean zipEntryMatch(String zeName, File[] files, String path){ - for(int i = 0; i < files.length; i++){ - if((path + files[i].getName()).equals(zeName)){ - return true; - } - } - return false; - } - - /** - * Create a copy for a file. - * @param src - * @param dst - * @throws IOException - */ - public void copyFile(File src, File dst) throws IOException { - InputStream is = null; - OutputStream os = null; - try { - is = new FileInputStream(src); - os = new FileOutputStream(dst); - byte[] buffer = new byte[1024]; - int length; - while ((length = is.read(buffer)) > 0) { - os.write(buffer, 0, length); - } - } finally { - is.close(); - os.close(); - } - } - - /** - * Check if the zip archive is being modified or referenced. - * @return - */ - public boolean isBusy() { - return this.busy; - } - - /* Prevent direct access to the constructor*/ - private ZipAppendUtil() { - super(); - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java index c4647466ee..d72a913a61 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java @@ -20,77 +20,107 @@ */ package org.biojava.nbio.structure.io.mmcif; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.HashSet; import java.util.Set; -import java.util.logging.Logger; import java.util.zip.GZIPInputStream; import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; import org.biojava.nbio.structure.io.mmcif.model.ChemComp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -/** This chemical component provider retrieves and caches chemical component definition files from a zip archive specified in its construction. - * If the archive does not contain the record, an attempt is made to download it using DownloadChemCompProvider. The downloaded file is then added to the archive. - * It is up to the calling function to handle exceptions raised by constructing with a non-existent archive. +/** This chemical component provider retrieves and caches chemical component definition files from a + * zip archive specified in its construction. If the archive does not contain the record, an attempt is + * made to download it using DownloadChemCompProvider. The downloaded file is then added to the archive. + * + * The class is thread-safe and the same ZipChemCompProvider should be used by all threads to prevent + * simultaneous read or write to the zip archive. A zip archive will be created if missing. * * @author edlunde * @author larsonm * @since 12/05/12 - * + * updated 3/5/2016 for Java 7 ZipFileSystem */ public class ZipChemCompProvider implements ChemCompProvider{ + private static final Logger s_logger = LoggerFactory.getLogger(ZipChemCompProvider.class); + + private final Path m_tempDir; // Base path where $m_zipRootDir/ will be downloaded to. + private final Path m_zipRootDir; + private final Path m_zipFile; + private final DownloadChemCompProvider m_dlProvider; + + private boolean m_removeCif; - private static final String FILE_SEPARATOR = System.getProperty("file.separator"); - private String tempdir = ""; // Base path where $zipRootDir/ will be downloaded to. - private String zipRootDir = "chemcomp/"; - private ZipFile zipDictionary; - private String zipFile; - private static final Logger s_logger = Logger.getLogger( ZipChemCompProvider.class.getPackage().getName() ); - private DownloadChemCompProvider dlProvider; - // Missing IDs from library that cannot be download added here to prevent delays. private Set unavailable = new HashSet(); /** - * - * @param chemicalComponentDictionaryFile : zip filename - * @param tempDir : directory of the zip filename + * ZipChemCompProvider is a Chemical Component provider that stores chemical components + * in a zip archive. Missing chemical components are downloaded and appended to the + * archive. If non-existent a new zip archive will be created. + * + * @param chemicalComponentDictionaryFile : path to zip archive for chemical components. + * @param tempDir : path for temporary directory, (null) defaults to path in property "java.io.tmpdir". * @throws IOException - */ - public ZipChemCompProvider(String chemicalComponentDictionaryFile, String tempDir) throws IOException{ - this.zipFile = chemicalComponentDictionaryFile; - this.tempdir = tempDir; - - init(); + */ + public ZipChemCompProvider(String chemicalComponentDictionaryFile, String tempDir) throws IOException { + this.m_zipFile = Paths.get(chemicalComponentDictionaryFile); + + // Use a default temporary directory if not passed a value. + if (tempDir == null || tempDir.equals("")) { + this.m_tempDir = Paths.get(System.getProperty("java.io.tmpdir")); + } else { + this.m_tempDir = Paths.get(tempDir); + } + + this.m_zipRootDir = Paths.get("chemcomp"); + + // Setup an instance of the download chemcomp provider. + this.m_dlProvider = new DownloadChemCompProvider(m_tempDir.toString()); + this.m_removeCif = true; + initializeZip(); } - - // Create the zip file and setup a fallback DownloadChemCompProvider. - private void init() throws IOException { - try{ - s_logger.info("Using chemical component dictionary: " + zipFile.toString()); - - // Check if file exists, if not create. - File zipFile = new File(this.zipFile); - if (!zipFile.exists()) { - createNewZip(zipFile); + + // See comments in addToZipFileSystem for why initialization is required with + // ZipFileSystems - due to URI issues in Java7. + private void initializeZip() throws IOException { + s_logger.info("Using chemical component dictionary: " + m_zipFile.toString()); + final File f = m_zipFile.toFile(); + if (!f.exists()) { + s_logger.info("Creating missing zip archive: " + m_zipFile.toString()); + FileOutputStream fo = new FileOutputStream(f); + ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(fo)); + try { + zip.putNextEntry(new ZipEntry("chemcomp/")); + zip.closeEntry(); + } finally { + zip.close(); } - - this.zipDictionary = new ZipFile(this.zipFile); - }catch(ZipException e){ - s_logger.info(e.getMessage()); } - - // Setup an instance of the download chemcomp provider. - dlProvider = new DownloadChemCompProvider(this.tempdir); + } + + /** + * Remove downloaded .cif.gz after adding to zip archive? + * Default is true. + * @param doRemove + */ + public void setRemoveCif(boolean doRemove) { + m_removeCif = doRemove; } /* (non-Javadoc) @@ -101,123 +131,61 @@ private void init() throws IOException { */ @Override public ChemComp getChemComp(String recordName) { - if (null == recordName) return null; // handle non-existent ChemComp codes and do not repeatedly attempt to add these. for (String str : unavailable) { if (recordName.equals(str)) return getEmptyChemComp(recordName); } - - try { - ZipEntry ccEntry = zipDictionary.getEntry(zipRootDir+recordName+".cif.gz"); - - //read single gzipped cif from archive and write to temporary file - InputStream zipStream = zipDictionary.getInputStream(ccEntry); - InputStream inputStream = new GZIPInputStream(zipStream); - s_logger.fine("reading "+recordName+" from " + zipFile); - MMcifParser parser = new SimpleMMcifParser(); - ChemCompConsumer consumer = new ChemCompConsumer(); - parser.addMMcifConsumer(consumer); - parser.parse(inputStream); - - ChemicalComponentDictionary dict = consumer.getDictionary(); - ChemComp cc = dict.getChemComp(recordName); - zipStream.close(); - if (cc != null){ - return cc; - } - }catch(NullPointerException npe){ - s_logger.info(npe.getMessage()+"\n"+"File "+recordName+" not found in archive. Attempting download from PDB."); - } - catch (Exception e) { - s_logger.info(e.getMessage()); - } - - //if file isn't found in archive, download it/add to archive - ChemComp cc = downloadAndAdd(recordName); - + + // Try to pull from zip, if fail then download. + ChemComp cc = getFromZip(recordName); if (cc == null) { - // Could not find this ChemComp, add this to a list of unavailable. + s_logger.info("File "+recordName+" not found in archive. Attempting download from PDB."); + cc = downloadAndAdd(recordName); + } + + // If a null record or an empty chemcomp, return a default ChemComp and blacklist. + if (cc == null || (null == cc.getName() && cc.getAtoms().size() == 0)) { + s_logger.info("Unable to find or download " + recordName + " - excluding from future searches."); unavailable.add(recordName); return getEmptyChemComp(recordName); } - return cc; - } - /** Use DownloadChemCompProvider to grab a gzipped cif record from the PDB. Zip all downloaded cif.gz files into the dictionary. - * */ - public ChemComp downloadAndAdd(String recordName){ - ChemComp cc = dlProvider.getChemComp(recordName); - - if (cc != null && "?".equals(cc.getOne_letter_code())) { - // Failed to find this chemical component and defaulted back to reduced chemical component. - unavailable.add(recordName); - return cc; // Don't try to add this to the chemcomp.zip. - } - - if(ZipAppendUtil.getInstance().isBusy()) { - return cc; - } - - String tmpdir = this.tempdir; - // Fall-back to java temporary directory if not set. - if (tmpdir == null || tmpdir.equals("")) { - tmpdir = System.getProperty("java.io.tmpdir"); - } - if ( !(tmpdir.endsWith(FILE_SEPARATOR) ) ) { - tmpdir += FILE_SEPARATOR; - } - tmpdir+="chemcomp"; - - final File [] files; - final File source; - try{ - files = finder(tmpdir, "cif.gz"); //DownloadProvider places files in default temp dir\chemcomp - source = new File(zipDictionary.getName()); - }catch(NullPointerException npe){ - return cc; - } + /** Use DownloadChemCompProvider to grab a gzipped cif record from the PDB. + * Zip all downloaded cif.gz files into the dictionary. + * + * @param recordName is the three-letter chemical component code (i.e. residue name). + * @return ChemComp matching recordName + */ + private ChemComp downloadAndAdd(String recordName){ + final ChemComp cc = m_dlProvider.getChemComp(recordName); - // Adding files could run on a separate thread, but more care is needed to prevent race - // conditions such as having asssembled a list of files to add/adding files while still writing an individual - // file to the temporary directory. Keeping this on one thread to prevent race conditions. - - // TODO: assess race conditions and make reassembling the zip a background task. - - //Thread updateArchiveThread = new Thread(new Runnable(){ - // public void run(){ - - if(! ZipAppendUtil.getInstance().isBusy()) { - ZipAppendUtil.getInstance().addToZipArchive(source, files, zipRootDir); - for (File f : files){ - f.delete(); - } - try { - zipDictionary.close(); - } catch (IOException e) { - s_logger.info(e.getMessage()); - } + // final File [] files = finder(m_tempDir.resolve("chemcomp").toString(), "cif.gz"); + final File [] files = new File[1]; + Path cif = m_tempDir.resolve("chemcomp").resolve(recordName + ".cif.gz"); + files[0] = cif.toFile(); + if (files != null) { + addToZipFileSystem(m_zipFile, files, m_zipRootDir); + if (m_removeCif) for (File f : files) f.delete(); } - // } - //}); - //updateArchiveThread.start(); - return cc; } /** - * Cleanup the temporary files that have been created within tmpdir. - */ - public static void purgeAllTempFiles(String tempdir) { - File[] ccOutFiles = finder(tempdir,"cif"); - for(File f : ccOutFiles) f.delete(); - File[] chemcompTempFiles = finderPrefix(tempdir, "chemcomp.zip"); - for(File f : chemcompTempFiles)f.delete(); - File chemcompDir = new File(System.getProperty("java.io.tmpdir") + FILE_SEPARATOR +"chemcomp"); - chemcompDir.delete(); + * Cleanup chemical component (.cif.gz) files downloaded to tmpdir. + * @param tempdir : path to temporary directory for chemical components + */ + public static void purgeTempFiles(String tempdir) { + if (tempdir == null) return; + + s_logger.info("Removing: "+tempdir); + Path dlPath = Paths.get(tempdir).resolve("chemcomp"); + File[] chemCompOutFiles = finder(dlPath.toString(), "cif.gz"); + if (null != chemCompOutFiles) for (File f : chemCompOutFiles) f.delete(); + dlPath.toFile().delete(); } /** @@ -226,11 +194,11 @@ public static void purgeAllTempFiles(String tempdir) { * @return */ private ChemComp getEmptyChemComp(String resName){ - String pdbName = ""; + String pdbName = ""; // Empty string is default if (null != resName && resName.length() >= 3) { pdbName = resName.substring(0,3); } - ChemComp comp = new ChemComp(); + final ChemComp comp = new ChemComp(); comp.setOne_letter_code("?"); comp.setThree_letter_code(pdbName); comp.setPolymerType(PolymerType.unknown); @@ -245,30 +213,100 @@ private ChemComp getEmptyChemComp(String resName){ * @return */ static private File[] finder( String dirName, final String suffix){ - File dir = new File(dirName); + if (null == dirName || null == suffix) { + return null; + } + + final File dir = new File(dirName); return dir.listFiles(new FilenameFilter() { public boolean accept(File dir, String filename) { return filename.endsWith(suffix); } } ); + } + + /** + * This is synchronized, along with addToFileSystem to prevent simulatenous reading/writing. + * @param recordName to find in zipfile. + * @return ChemComp if found or null if missing. + */ + private synchronized ChemComp getFromZip(String recordName) { + ChemComp cc = null; + if (!m_zipFile.toFile().exists()) return cc; + final String filename = "chemcomp/" + recordName+".cif.gz"; + + // try with resources block to read from the filesystem. + try (FileSystem fs = FileSystems.newFileSystem(m_zipFile, null)) { + Path cif = fs.getPath(filename); + + if (Files.exists(cif)) { + final InputStream zipStream = Files.newInputStream(cif); + final InputStream inputStream = new GZIPInputStream(zipStream); + s_logger.debug("reading " + recordName + " from " + m_zipFile); + final MMcifParser parser = new SimpleMMcifParser(); + final ChemCompConsumer consumer = new ChemCompConsumer(); + parser.addMMcifConsumer(consumer); + parser.parse(inputStream); + inputStream.close(); + + final ChemicalComponentDictionary dict = consumer.getDictionary(); + cc = dict.getChemComp(recordName); + } + } catch (IOException e) { + s_logger.error("Unable to read from zip file : " + e.getMessage()); + } + return cc; } - + /** - * Return File(s) in dirName that match prefix. - * @param dirName - * @param prefix - * @return + * Add an array of files to a zip archive. + * Synchronized to prevent simultaneous reading/writing. + * + * @param zipFile is a destination zip archive + * @param files is an array of files to be added + * @param pathWithinArchive is the path within the archive to add files to + * @return true if successfully appended these files. */ - static private File[] finderPrefix( String dirName, final String prefix){ - File dir = new File(dirName); - return dir.listFiles(new FilenameFilter() { - public boolean accept(File dir, String filename) - { return filename.startsWith(prefix); } - } ); - } - - private void createNewZip(File f) throws IOException { - final ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f)); - out.close(); + private synchronized boolean addToZipFileSystem(Path zipFile, File[] files, Path pathWithinArchive) { + boolean ret = false; + + /* URIs in Java 7 cannot have spaces, must use Path instead + * and so, cannot use the properties map to describe need to create + * a new zip archive. ZipChemCompProvider.initilizeZip to creates the + * missing zip file */ + + /* + // convert the filename to a URI + String uriString = "jar:file:" + zipFile.toUri().getPath(); + final URI uri = URI.create(uriString); + + // if filesystem doesn't exist, create one. + final Map env = new HashMap<>(); + // Create a new zip if one isn't present. + if (!zipFile.toFile().exists()) { + System.out.println("Need to create " + zipFile.toString()); + } + env.put("create", String.valueOf(!zipFile.toFile().exists())); + // Specify the encoding as UTF -8 + env.put("encoding", "UTF-8"); + */ + + // Copy in each file. + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, null)) { + Files.createDirectories(pathWithinArchive); + for (File f : files) { + if (!f.isDirectory() && f.exists()) { + Path externalFile = f.toPath(); + Path pathInZipFile = zipfs.getPath(pathWithinArchive.resolve(f.getName()).toString()); + Files.copy(externalFile, pathInZipFile, + StandardCopyOption.REPLACE_EXISTING); + } + } + ret = true; + } catch (IOException ex) { + s_logger.error("Unable to add entries to Chemical Component zip archive : " + ex.getMessage()); + ret = false; + } + return ret; } -} +} \ No newline at end of file diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java index 435f78731d..5813d98d4e 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java @@ -9,13 +9,19 @@ import java.nio.file.Paths; import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureIO; +import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.align.util.UserConfiguration; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileReader; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TestChemCompProvider { - + private static final Logger s_logger = LoggerFactory.getLogger(TestChemCompProvider.class); + // Short test with bad ligand name (QNA is bogus) final String DNAexample = @@ -100,8 +106,10 @@ public void testZipChemCompProvider() throws IOException { Path chemComp = pdbdir.resolve("chemcomp.zip"); System.out.println("Using PDB_DIR=" + pdbdir.toString() + " as temporary file directory"); - - ChemCompGroupFactory.setChemCompProvider(new ZipChemCompProvider(chemComp.toString(), pdbdir.toString())); + ZipChemCompProvider zp = new ZipChemCompProvider(chemComp.toString(), pdbdir.toString()); + // Keep the .cif.gz files - avoid re-downloading for unit testing. + zp.setRemoveCif(false); + ChemCompGroupFactory.setChemCompProvider(zp); // Parameters FileParsingParameters params = new FileParsingParameters(); @@ -112,5 +120,50 @@ public void testZipChemCompProvider() throws IOException { Structure s = pdbreader.getStructure(testPDB); assertEquals(5, s.getChain(0).getAtomGroups().size()); + // Not wanted here for testing, but useful for cleaning up downloaded .cif.gz files. + // ZipChemCompProvider.purgeTempFiles(pdbdir.toString()); + } + + @Test + public void testNormalStructure() throws StructureException, IOException { + // we just need this to track where to store PDB files + // this checks the PDB_DIR property (and uses a tmp location if not set) + UserConfiguration config = new UserConfiguration(); + String cachePath = config.getCacheFilePath(); + + // Setup a ChemCompProvider + Path pdbdir = Paths.get(cachePath); + Path chemComp = pdbdir.resolve("chemcomp.zip"); + + System.out.println("Using PDB_DIR=" + pdbdir.toString() + " as temporary file directory"); + + AtomCache cache = new AtomCache(); + StructureIO.setAtomCache(cache); + FileParsingParameters params = cache.getFileParsingParams(); + params.setParseBioAssembly(true); + params.setLoadChemCompInfo(true); + + /* + ChemCompGroupFactory.setChemCompProvider(new DownloadChemCompProvider()); + StructureIO.setAtomCache(cache); + cache.setUseMmCif(true); + long startTime = System.currentTimeMillis(); + Structure sCif = StructureIO.getStructure("4HHM"); + long finishTime = System.currentTimeMillis(); + s_logger.info("DownloadChemComp time: "+(finishTime-startTime)+ " ms"); + */ + + ZipChemCompProvider zp = new ZipChemCompProvider(chemComp.toString(), pdbdir.toString()); + // Keep the .cif.gz files - avoid re-downloading for unit testing. + zp.setRemoveCif(false); + ChemCompGroupFactory.setChemCompProvider(zp); + + long startTime = System.currentTimeMillis(); + Structure sCif = StructureIO.getStructure("4HHM"); + long finishTime = System.currentTimeMillis(); + s_logger.info("ZipChemComp time: "+(finishTime-startTime)+ " ms"); + + // Not wanted here for testing, but useful for cleaning up downloaded .cif.gz files. + // ZipChemCompProvider.purgeTempFiles(pdbdir.toString()); } }