Skip to content

Commit 9080b37

Browse files
committed
Completed procedure for SearchIO constructor with Factory guess. This will allow auto selection of the appropriate parser based on file extension. Tests added.
1 parent 24fab31 commit 9080b37

File tree

4 files changed

+150
-69
lines changed

4 files changed

+150
-69
lines changed

biojava-core/src/main/java/org/biojava/nbio/core/search/io/SearchIO.java

Lines changed: 53 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77
package org.biojava.nbio.core.search.io;
88

99
import java.io.File;
10-
import java.net.URL;
11-
import java.util.ArrayList;
1210
import java.util.HashMap;
1311
import java.util.Iterator;
1412
import java.util.List;
13+
import java.util.ServiceLoader;
1514

1615
/**
1716
*
1817
* @author pavanpa
1918
*/
2019
public class SearchIO implements Iterable<Result>{
21-
private HashMap<String,ResultFactory> extensionFactoryAssociation;
20+
static private HashMap<String,ResultFactory> extensionFactoryAssociation;
21+
22+
private ResultFactory factory;
23+
private File file;
2224

2325
/**
2426
* this threshold applies in retrieving hsp. Those having e-value below this
@@ -31,32 +33,68 @@ public class SearchIO implements Iterable<Result>{
3133
*/
3234
private List<Result> results;
3335

34-
private final String NOT_SUPPORTED_FILE_EXCEPTION = "This extension is not associated with any parser.";
36+
private final String NOT_SUPPORTED_FILE_EXCEPTION =
37+
"This extension is not associated with any parser. You can try to specify a ResultFactory object.";
3538

39+
/**
40+
* Build a SearchIO reader and tries to select the appropriate parser inspecting
41+
* file extension.
42+
*
43+
* @param f
44+
* @throws Exception
45+
*/
3646
public SearchIO (File f) throws Exception{
37-
//this(f,getFactory(f));
47+
factory = guessFactory(f);
48+
file = f;
49+
process();
3850
}
3951

52+
/**
53+
* Build a SearchIO reader and specify a ResultFactory object to be used
54+
* for parsing
55+
*
56+
* @param f
57+
* @param factory
58+
* @throws Exception
59+
*/
4060
public SearchIO (File f, ResultFactory factory) throws Exception{
41-
factory.setFile(f);
42-
results = factory.createObjects(evalueThreshold);
61+
file = f;
62+
this.factory = factory;
63+
process();
4364
}
44-
65+
/**
66+
* Build a SearchIO reader, specify a ResultFactory object to be used for parsing
67+
* and filter hsp retrieved by a e-value threshold.
68+
* This usually increase parsing speed
69+
* @param f
70+
* @param factory
71+
* @param maxEvalue
72+
* @throws Exception
73+
*/
4574
public SearchIO(File f, ResultFactory factory, double maxEvalue) throws Exception{
75+
file = f;
76+
this.factory = factory;
4677
this.evalueThreshold = maxEvalue;
47-
factory.setFile(f);
78+
process();
79+
}
80+
81+
private void process() throws Exception {
82+
factory.setFile(file);
4883
results = factory.createObjects(evalueThreshold);
4984
}
5085

5186
private ResultFactory guessFactory(File f){
52-
List<Class<?>> classes = FactoryLoader.find("Bio.SearchIO.ConcreteFactories");
53-
87+
if (extensionFactoryAssociation == null){
88+
extensionFactoryAssociation = new HashMap<String, ResultFactory>();
89+
ServiceLoader<ResultFactory> impl = ServiceLoader.load(ResultFactory.class);
90+
for (ResultFactory loadedImpl : impl) {
91+
List<String> fileExtensions = loadedImpl.getFileExtensions();
92+
for (String ext: fileExtensions) extensionFactoryAssociation.put(ext, loadedImpl);
93+
}
94+
}
95+
5496
String filename = f.getAbsolutePath();
5597
int extensionPos = filename.lastIndexOf(".");
56-
/*
57-
int lastSeparator = indexOfLastSeparator(filename);
58-
return (lastSeparator > extensionPos ? -1 : extensionPos);
59-
*/
6098
String extension = filename.substring(extensionPos + 1);
6199
if (extensionFactoryAssociation.get(extension) == null)
62100
throw new UnsupportedOperationException(NOT_SUPPORTED_FILE_EXCEPTION
@@ -89,57 +127,4 @@ public void remove() {
89127
}
90128
};
91129
}
92-
93-
94-
95-
96130
}
97-
/**
98-
* da :
99-
* http://stackoverflow.com/questions/15519626/how-to-get-all-classes-names-in-a-package
100-
* @author pavanpa
101-
*/
102-
class FactoryLoader {
103-
private static final char DOT = '.';
104-
105-
private static final char SLASH = '/';
106-
107-
private static final String CLASS_SUFFIX = ".class";
108-
109-
private static final String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the package '%s' exists?";
110-
111-
public static List<Class<?>> find(String scannedPackage) {
112-
String scannedPath = scannedPackage.replace(DOT, SLASH);
113-
URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(scannedPath);
114-
115-
if (scannedUrl == null) {
116-
throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPath, scannedPackage));
117-
}
118-
File scannedDir = new File(scannedUrl.getFile());
119-
List<Class<?>> classes = new ArrayList<Class<?>>();
120-
for (File file : scannedDir.listFiles()) {
121-
classes.addAll(find(file, scannedPackage));
122-
}
123-
return classes;
124-
}
125-
126-
private static List<Class<?>> find(File file, String scannedPackage) {
127-
List<Class<?>> classes = new ArrayList<Class<?>>();
128-
String resource = scannedPackage + DOT + file.getName();
129-
if (file.isDirectory()) {
130-
for (File child : file.listFiles()) {
131-
classes.addAll(find(child, resource));
132-
}
133-
} else if (resource.endsWith(CLASS_SUFFIX)) {
134-
int endIndex = resource.length() - CLASS_SUFFIX.length();
135-
String className = resource.substring(0, endIndex);
136-
try {
137-
classes.add(Class.forName(className));
138-
} catch (ClassNotFoundException ignore) {
139-
}
140-
}
141-
return classes;
142-
}
143-
144-
}
145-

biojava-core/src/main/java/org/biojava/nbio/core/search/io/blast/BlastTabularParser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ private enum PARSING_CONSISTENCY {
6868

6969
@Override
7070
public List<String> getFileExtensions() {
71-
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
71+
List l = new ArrayList();
72+
l.add("blasttabular");
73+
l.add("blasttxt");
74+
return l;
7275
}
7376

7477
@Override
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
org.biojava.nbio.core.search.io.blast.BlastXMLQuery
2+
org.biojava.nbio.core.search.io.blast.BlastTabularParser
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* To change this license header, choose License Headers in Project Properties.
3+
* To change this template file, choose Tools | Templates
4+
* and open the template in the editor.
5+
*/
6+
package org.biojava.nbio.core.search.io;
7+
8+
import java.io.File;
9+
import java.net.URL;
10+
import java.util.Iterator;
11+
import org.biojava.nbio.core.search.io.blast.BlastXMLQuery;
12+
import org.junit.After;
13+
import org.junit.AfterClass;
14+
import org.junit.Before;
15+
import org.junit.BeforeClass;
16+
import org.junit.Test;
17+
import static org.junit.Assert.*;
18+
import org.junit.Ignore;
19+
20+
/**
21+
*
22+
* @author pavanpa
23+
*/
24+
public class SearchIOTest {
25+
26+
public SearchIOTest() {
27+
}
28+
29+
@BeforeClass
30+
public static void setUpClass() {
31+
}
32+
33+
@AfterClass
34+
public static void tearDownClass() {
35+
}
36+
37+
@Before
38+
public void setUp() {
39+
}
40+
41+
@After
42+
public void tearDown() {
43+
}
44+
45+
@Test
46+
public void testConstructorWithFactoryGuess() {
47+
System.out.println("Constructor test with GuessFactory");
48+
String resource = "/org/biojava/nbio/core/search/io/blast/test.two-query.blasttxt";
49+
URL resourceURL = getClass().getResource(resource);
50+
File file = new File(resourceURL.getFile());
51+
52+
final SearchIO instance;
53+
try {
54+
instance = new SearchIO(file);
55+
} catch (Exception e) {
56+
fail("test failed:\n"+e.getMessage());
57+
}
58+
}
59+
60+
@Test
61+
public void testConstructorWithoutFactoryGuess() {
62+
System.out.println("Constructor test specifying Factory");
63+
String resource = "/org/biojava/nbio/core/search/io/blast/testBlastReport.xml";
64+
URL resourceURL = getClass().getResource(resource);
65+
File file = new File(resourceURL.getFile());
66+
67+
ResultFactory blastResultFactory = new BlastXMLQuery();
68+
final SearchIO instance;
69+
try {
70+
instance = new SearchIO(file, blastResultFactory);
71+
} catch (Exception e) {
72+
fail("test failed:\n"+e.getMessage());
73+
}
74+
}
75+
76+
@Test
77+
public void testConstructorWithEvalueHspFilter() {
78+
System.out.println("Constructor test specifying Factory");
79+
String resource = "/org/biojava/nbio/core/search/io/blast/testBlastReport.xml";
80+
URL resourceURL = getClass().getResource(resource);
81+
File file = new File(resourceURL.getFile());
82+
83+
ResultFactory blastResultFactory = new BlastXMLQuery();
84+
final SearchIO instance;
85+
try {
86+
instance = new SearchIO(file, blastResultFactory, 10e-10);
87+
} catch (Exception e) {
88+
fail("test failed:\n"+e.getMessage());
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)