9c2bfd42bcbfe96a34e6764e0ce252a7b051334b
[jalview.git] / src / jalview / ws / seqfetcher / ASequenceFetcher.java
1 package jalview.ws.seqfetcher;\r
2 \r
3 import jalview.datamodel.AlignmentI;\r
4 import jalview.datamodel.SequenceI;\r
5 \r
6 import java.util.Enumeration;\r
7 import java.util.Hashtable;\r
8 import java.util.Vector;\r
9 \r
10 public class ASequenceFetcher\r
11 {\r
12 \r
13   /**\r
14    * set of databases we can retrieve entries from\r
15    */\r
16   protected Hashtable FETCHABLEDBS;\r
17 \r
18   public ASequenceFetcher()\r
19   {\r
20     super();\r
21   }\r
22 \r
23   /**\r
24    * get list of supported Databases\r
25    * \r
26    * @return database source string for each database - only the latest version\r
27    *         of a source db is bound to each source.\r
28    */\r
29   public String[] getSupportedDb()\r
30   {\r
31     if (FETCHABLEDBS == null)\r
32       return null;\r
33     String[] sf = new String[FETCHABLEDBS.size()];\r
34     Enumeration e = FETCHABLEDBS.keys();\r
35     int i = 0;\r
36     while (e.hasMoreElements())\r
37     {\r
38       sf[i++] = (String) e.nextElement();\r
39     }\r
40     ;\r
41     return sf;\r
42   }\r
43 \r
44   public boolean isFetchable(String source)\r
45   {\r
46     Enumeration e = FETCHABLEDBS.keys();\r
47     while (e.hasMoreElements())\r
48     {\r
49       String db = (String) e.nextElement();\r
50       if (source.compareToIgnoreCase(db) == 0)\r
51         return true;\r
52     }\r
53     jalview.bin.Cache.log.warn("isFetchable doesn't know about '" + source\r
54             + "'");\r
55     return false;\r
56   }\r
57 \r
58   public SequenceI[] getSequences(jalview.datamodel.DBRefEntry[] refs)\r
59   {\r
60     SequenceI[] ret = null;\r
61     Vector rseqs = new Vector();\r
62     Hashtable queries = new Hashtable();\r
63     for (int r = 0; r < refs.length; r++)\r
64     {\r
65       if (!queries.containsKey(refs[r].getSource()))\r
66       {\r
67         queries.put(refs[r].getSource(), new Vector());\r
68       }\r
69       Vector qset = (Vector) queries.get(refs[r].getSource());\r
70       if (!qset.contains(refs[r].getAccessionId()))\r
71       {\r
72         qset.addElement(refs[r].getAccessionId());\r
73       }\r
74     }\r
75     Enumeration e = queries.keys();\r
76     while (e.hasMoreElements())\r
77     {\r
78       Vector query = null;\r
79       String db = null;\r
80       try\r
81       {\r
82         db = (String) e.nextElement();\r
83         query = (Vector) queries.get(db);\r
84         if (!isFetchable(db))\r
85           throw new Exception(\r
86                   "Don't know how to fetch from this database :" + db);\r
87         DbSourceProxy fetcher = getSourceProxy(db);\r
88         boolean doMultiple = fetcher.getAccessionSeparator() != null; // No\r
89                                                                       // separator\r
90                                                                       // - no\r
91                                                                       // Multiple\r
92                                                                       // Queries\r
93         Enumeration qs = query.elements();\r
94         while (qs.hasMoreElements())\r
95         {\r
96           StringBuffer qsb = new StringBuffer();\r
97           do\r
98           {\r
99             qsb.append((String) qs.nextElement());\r
100             if (qs.hasMoreElements() && doMultiple) // and not reached limit for\r
101                                                     // multiple queries at one\r
102                                                     // time for this source\r
103             {\r
104               qsb.append(fetcher.getAccessionSeparator());\r
105             }\r
106           } while (doMultiple && qs.hasMoreElements());\r
107           \r
108           AlignmentI seqset=null;\r
109           try {\r
110             // create a fetcher and go to it\r
111             seqset = fetcher.getSequenceRecords(qsb.toString());\r
112           } catch (Exception ex)\r
113           {\r
114             System.err.println("Failed to retrieve the following from "+db);\r
115             System.err.println(qsb);\r
116             ex.printStackTrace(System.err);\r
117           }\r
118           // TODO: Merge alignment together - perhaps\r
119           if (seqset != null)\r
120           {\r
121             SequenceI seqs[] = seqset.getSequencesArray();\r
122             if (seqs != null)\r
123             {\r
124               for (int is = 0; is < seqs.length; is++)\r
125               {\r
126                 rseqs.addElement(seqs[is]);\r
127                 seqs[is] = null;\r
128               }\r
129             }\r
130             else\r
131             {\r
132               if (fetcher.getRawRecords() != null)\r
133               {\r
134                 System.out.println("# Retrieved from " + db + ":"\r
135                         + qs.toString());\r
136                 StringBuffer rrb = fetcher.getRawRecords();\r
137                 /*\r
138                  * for (int rr = 0; rr<rrb.length; rr++) {\r
139                  */\r
140                 String hdr;\r
141                 // if (rr<qs.length)\r
142                 // {\r
143                 hdr = "# " + db + ":" + qsb.toString();\r
144                 /*\r
145                  * } else { hdr = "# part "+rr; }\r
146                  */\r
147                 System.out.println(hdr);\r
148                 if (rrb != null)\r
149                   System.out.println(rrb);\r
150                 System.out.println("# end of " + hdr);\r
151               }\r
152             }\r
153           }\r
154         }\r
155       } catch (Exception ex)\r
156       {\r
157         System.err\r
158                 .println("Failed to retrieve the following references from "\r
159                         + db);\r
160         Enumeration qv = query.elements();\r
161         int n = 0;\r
162         while (qv.hasMoreElements())\r
163         {\r
164           System.err.print(" " + qv.nextElement() + ";");\r
165           if (n++ > 10)\r
166           {\r
167             System.err.println();\r
168             n = 0;\r
169           }\r
170         }\r
171         System.err.println();\r
172         ex.printStackTrace();\r
173       }\r
174     }\r
175     if (rseqs.size() > 0)\r
176     {\r
177       ret = new SequenceI[rseqs.size()];\r
178       Enumeration sqs = rseqs.elements();\r
179       int si=0;\r
180       while (sqs.hasMoreElements())\r
181       {\r
182         SequenceI s = (SequenceI) sqs.nextElement();\r
183         ret[si++] = s;\r
184         s.updatePDBIds();\r
185       }\r
186     }\r
187     return ret;\r
188   }\r
189 \r
190   /**\r
191    * Retrieve an instance of the proxy for the given source\r
192    * \r
193    * @param db\r
194    *          database source string TODO: add version string/wildcard for\r
195    *          retrieval of specific DB source/version combinations.\r
196    * @return an instance of DbSourceProxy for that db.\r
197    */\r
198   public DbSourceProxy getSourceProxy(String db)\r
199   {\r
200     DbSourceProxy dbs = (DbSourceProxy) FETCHABLEDBS.get(db);\r
201     return dbs;\r
202   }\r
203 \r
204   /**\r
205    * constructs and instance of the proxy and registers it as a valid\r
206    * dbrefsource\r
207    * \r
208    * @param dbSourceProxy\r
209    *                reference for class implementing\r
210    *                jalview.ws.seqfetcher.DbSourceProxy\r
211    * @throws java.lang.IllegalArgumentException\r
212    *                 if class does not implement\r
213    *                 jalview.ws.seqfetcher.DbSourceProxy\r
214    */\r
215   protected void addDBRefSourceImpl(Class dbSourceProxy)\r
216           throws java.lang.IllegalArgumentException\r
217   {\r
218     try\r
219     {\r
220       Object proxyObj = dbSourceProxy.getConstructor(\r
221               null).newInstance(null);\r
222       if (!DbSourceProxy.class.isInstance(proxyObj))\r
223       {\r
224         throw new IllegalArgumentException(\r
225                 dbSourceProxy.toString()\r
226                         + " does not implement the jalview.ws.seqfetcher.DbSourceProxy");\r
227       }\r
228       DbSourceProxy proxy = (DbSourceProxy) proxyObj; \r
229       if (proxy != null)\r
230       {\r
231         if (FETCHABLEDBS == null)\r
232         {\r
233           FETCHABLEDBS = new Hashtable();\r
234         }\r
235         FETCHABLEDBS.put(proxy.getDbSource(), proxy);\r
236       }\r
237     } \r
238     catch (IllegalArgumentException e)\r
239     {\r
240       throw e;\r
241     }\r
242     catch (Exception e)\r
243     {\r
244       // Serious problems if this happens.\r
245       throw new Error("DBRefSource Implementation Exception", e);\r
246     }\r
247   }\r
248 \r
249 }