new DBRef management and generalised source and entry retrieval mechanism for referen...
[jalview.git] / src / jalview / ws / ASequenceFetcher.java
1 package jalview.ws;\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           // create a fetcher and go to it\r
109           AlignmentI seqset = fetcher.getSequenceRecords(qsb.toString());\r
110           // TODO: Merge alignment together - perhaps\r
111           if (seqset != null)\r
112           {\r
113             SequenceI seqs[] = seqset.getSequencesArray();\r
114             if (seqs != null)\r
115             {\r
116               for (int is = 0; is < seqs.length; is++)\r
117               {\r
118                 rseqs.addElement(seqs[is]);\r
119                 seqs[is] = null;\r
120               }\r
121             }\r
122             else\r
123             {\r
124               if (fetcher.getRawRecords() != null)\r
125               {\r
126                 System.out.println("# Retrieved from " + db + ":"\r
127                         + qs.toString());\r
128                 StringBuffer rrb = fetcher.getRawRecords();\r
129                 /*\r
130                  * for (int rr = 0; rr<rrb.length; rr++) {\r
131                  */\r
132                 String hdr;\r
133                 // if (rr<qs.length)\r
134                 // {\r
135                 hdr = "# " + db + ":" + qsb.toString();\r
136                 /*\r
137                  * } else { hdr = "# part "+rr; }\r
138                  */\r
139                 System.out.println(hdr);\r
140                 if (rrb != null)\r
141                   System.out.println(rrb);\r
142                 System.out.println("# end of " + hdr);\r
143               }\r
144             }\r
145           }\r
146         }\r
147       } catch (Exception ex)\r
148       {\r
149         System.err\r
150                 .println("Failed to retrieve the following references from "\r
151                         + db);\r
152         Enumeration qv = query.elements();\r
153         int n = 0;\r
154         while (qv.hasMoreElements())\r
155         {\r
156           System.err.print(" " + qv + ";");\r
157           if (n++ > 10)\r
158           {\r
159             System.err.println();\r
160             n = 0;\r
161           }\r
162         }\r
163         System.err.println();\r
164         ex.printStackTrace();\r
165       }\r
166     }\r
167     if (rseqs.size() > 0)\r
168     {\r
169       ret = new SequenceI[rseqs.size()];\r
170       rseqs.copyInto(ret);\r
171     }\r
172     return ret;\r
173   }\r
174 \r
175   /**\r
176    * Retrieve an instance of the proxy for the given source\r
177    * \r
178    * @param db\r
179    *          database source string TODO: add version string/wildcard for\r
180    *          retrieval of specific DB source/version combinations.\r
181    * @return an instance of DbSourceProxy for that db.\r
182    */\r
183   public DbSourceProxy getSourceProxy(String db)\r
184   {\r
185     DbSourceProxy dbs = (DbSourceProxy) FETCHABLEDBS.get(db);\r
186     return dbs;\r
187   }\r
188 \r
189 }