77package org .biojava .nbio .core .search .io ;
88
99import java .io .File ;
10- import java .net .URL ;
11- import java .util .ArrayList ;
1210import java .util .HashMap ;
1311import java .util .Iterator ;
1412import java .util .List ;
13+ import java .util .ServiceLoader ;
1514
1615/**
1716 *
1817 * @author pavanpa
1918 */
2019public 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-
0 commit comments