diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cath/CathInstallation.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cath/CathInstallation.java index a72e85ed16..4201f8d5ca 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cath/CathInstallation.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cath/CathInstallation.java @@ -350,13 +350,15 @@ private void parseCathDomainList() throws IOException { parseCathDomainList(buffer); } - private void parseCathDomainList(BufferedReader bufferedReader) throws IOException{ + protected void parseCathDomainList(BufferedReader bufferedReader) throws IOException{ String line; - // int counter = 0; + int counter = 0; while ( (line = bufferedReader.readLine()) != null ) { if ( line.startsWith("#") ) continue; + if ( line.trim().isEmpty() ) continue; CathDomain cathDomain = parseCathListFileLine(line); - // counter++; + if ( cathDomain == null ) continue; + counter++; String pdbId = cathDomain.getPdbIdAndChain().substring(0,4); // includes chain letter @@ -372,6 +374,9 @@ private void parseCathDomainList(BufferedReader bufferedReader) throws IOExcepti domainMap.put( cathDomain.getDomainName(), cathDomain ); } + if (counter == 0) { + throw new IOException("Could not parse any CATH domains from the domain list file."); + } } private void parseCathNames() throws IOException { @@ -386,7 +391,9 @@ private void parseCathNames(BufferedReader bufferedReader) throws IOException{ //int counter = 0; while ( (line = bufferedReader.readLine()) != null ) { if ( line.startsWith("#") ) continue; + if ( line.trim().isEmpty() ) continue; CathNode cathNode = parseCathNamesFileLine(line); + if ( cathNode == null ) continue; cathTree.put(cathNode.getNodeId(), cathNode); } } @@ -413,6 +420,7 @@ private void parseCathDomainDescriptionFile(BufferedReader bufferedReader) throw StringBuilder sseqs = null; while ( (line = bufferedReader.readLine()) != null ) { if ( line.startsWith("#") ) continue; + if ( line.trim().isEmpty() ) continue; if ( line.startsWith("FORMAT") ) { cathDescription = new CathDomain(); cathDescription.setFormat( line.substring(10) ); @@ -504,8 +512,11 @@ private void parseCathDomainDescriptionFile(BufferedReader bufferedReader) throw }*/ private CathDomain parseCathListFileLine(String line) { + String [] token = line.trim().split("\\s+"); + if (token.length < 12) { + return null; + } CathDomain cathDomain = new CathDomain(); - String [] token = line.split("\\s+"); cathDomain.setDomainName(token[0]); cathDomain.setClassId(Integer.parseInt(token[1])); cathDomain.setArchitectureId(Integer.parseInt(token[2])); @@ -522,8 +533,12 @@ private CathDomain parseCathListFileLine(String line) { } private CathNode parseCathNamesFileLine(String line) { + String[] token = line.trim().split("\\s+",3); + if (token.length < 3) { + LOGGER.debug("Invalid line in cath names file, was expecting 3 tokens but got {} tokens: {}", token.length, line); + return null; + } CathNode cathNode = new CathNode(); - String[] token = line.split("\\s+",3); cathNode.setNodeId( token[0] ); int idx = token[0].lastIndexOf("."); if ( idx == -1 ) idx = token[0].length(); @@ -544,8 +559,8 @@ private void parseCathDomall(BufferedReader bufferedReader) throws IOException{ String line; while ( ((line = bufferedReader.readLine()) != null) ) { if ( line.startsWith("#") ) continue; - if ( line.length() == 0 ) continue; - String[] token = line.split("\\s+"); + if ( line.trim().isEmpty() ) continue; + String[] token = line.trim().split("\\s+"); String chainId = token[0]; Integer numberOfDomains = Integer.parseInt( token[1].substring(1) ); Integer numberOfFragments = Integer.parseInt( token[2].substring(1) ); @@ -671,25 +686,25 @@ protected void downloadFileFromRemote(URL remoteURL, File localFile) throws IOEx private boolean domainDescriptionFileAvailable(){ String fileName = getDomainDescriptionFileName(); File f = new File(fileName); - return f.exists(); + return f.exists() && FileDownloadUtils.validateFile(f); } private boolean domainListFileAvailable(){ String fileName = getDomainListFileName(); File f = new File(fileName); - return f.exists(); + return f.exists() && FileDownloadUtils.validateFile(f); } private boolean nodeListFileAvailable(){ String fileName = getNodeListFileName(); File f = new File(fileName); - return f.exists(); + return f.exists() && FileDownloadUtils.validateFile(f); } private boolean domallFileAvailable() { String fileName = getDomallFileName(); File f= new File(fileName); - return f.exists(); + return f.exists() && FileDownloadUtils.validateFile(f); } protected void downloadDomainListFile() throws IOException{ diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/cath/CathInstallationTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/cath/CathInstallationTest.java new file mode 100644 index 0000000000..69944cb51c --- /dev/null +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/cath/CathInstallationTest.java @@ -0,0 +1,87 @@ +/* + * 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.cath; + +import org.junit.jupiter.api.Test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class CathInstallationTest { + + @Test + public void testParseCathDomainListSuccess() throws IOException { + String data = "# CATH domain list\n" + + "\n" + + "1oaiA00 1 10 490 10 1 1 1 1 1 124 1.80\n" + + "1oaiA01 1 10 490 10 1 1 1 1 2 150 1.80\n"; + + CathInstallation installation = new CathInstallation(""); + BufferedReader reader = new BufferedReader(new StringReader(data)); + installation.parseCathDomainList(reader); + installation.setInstalledDomainList(new AtomicBoolean(true)); //1 + installation.setInstalledDomall(new AtomicBoolean(true)); //2 + + CathDomain domain = installation.getDomainByCathId("1oaiA00"); + assertNotNull(domain); + assertEquals("1oaiA00", domain.getDomainName()); + assertEquals(1, domain.getClassId()); + assertEquals(10, domain.getArchitectureId()); + assertEquals(490, domain.getTopologyId()); + assertEquals(10, domain.getHomologyId()); + assertEquals(124, domain.getLength()); + assertEquals(1.80, domain.getResolution(), 0.001); + } + + @Test + public void testParseCathDomainListEmptyThrowsException() { + CathInstallation installation = new CathInstallation(""); + BufferedReader reader = new BufferedReader(new StringReader("")); + assertThrows(IOException.class, () -> installation.parseCathDomainList(reader)); + } + + @Test + public void testParseCathDomainListOnlyCommentsAndWhitespaceThrowsException() { + String data = "# comment 1\n" + + "# comment 2\n" + + " \n" + + "\t\n"; + CathInstallation installation = new CathInstallation(""); + BufferedReader reader = new BufferedReader(new StringReader(data)); + assertThrows(IOException.class, () -> installation.parseCathDomainList(reader)); + } + + @Test + public void testParseCathDomainListNoParsableLinesThrowsException() { + String data = "# comment\n" + + "invalid line with too few tokens\n" + + "another bad line\n"; + CathInstallation installation = new CathInstallation(""); + BufferedReader reader = new BufferedReader(new StringReader(data)); + IOException exception = assertThrows(IOException.class, () -> installation.parseCathDomainList(reader)); + assertNotNull(exception.getMessage()); + } +}