Properties bug fixed
[jalview.git] / src / jalview / analysis / SequenceFeatureFetcher.java
1 package jalview.analysis;\r
2 \r
3 import java.io.*;\r
4 import java.util.*;\r
5 import jalview.io.*;\r
6 import jalview.gui.*;\r
7 import jalview.datamodel.*;\r
8 \r
9 public class SequenceFeatureFetcher implements Runnable\r
10 {\r
11   AlignmentI align;\r
12   AlignmentPanel ap;\r
13 \r
14   public SequenceFeatureFetcher(AlignmentI align, AlignmentPanel ap)\r
15   {\r
16     this.align = align;\r
17     this.ap = ap;\r
18     Thread thread = new Thread(this);\r
19     thread.start();\r
20   }\r
21 \r
22   public void run()\r
23 {\r
24 \r
25   String cache = jalview.bin.Cache.getProperty("UNIPROT_CACHE");\r
26 \r
27   RandomAccessFile out = null;\r
28 \r
29   try{\r
30     if (cache == null)\r
31     {\r
32       jalview.bin.Cache.setProperty("UNIPROT_CACHE", System.getProperty("user.home")+"/uniprot.xml");\r
33       cache = jalview.bin.Cache.getProperty("UNIPROT_CACHE");\r
34     }\r
35 \r
36 \r
37 \r
38     File test = new File(cache);\r
39     if( !test.exists() )\r
40     {\r
41       out = new RandomAccessFile(cache, "rw");\r
42       out.writeBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");\r
43       out.writeBytes("<UNIPROT_CACHE>\n");\r
44     }\r
45     else\r
46     {\r
47       out = new RandomAccessFile(cache, "rw");\r
48       // open exisiting cache and remove </UNIPROT_CACHE> from the end\r
49       long lastLine = 0;\r
50       String data;\r
51       while ( (data = out.readLine()) != null)\r
52       {\r
53         if (data.indexOf("</entry>") > -1)\r
54           lastLine = out.getFilePointer();\r
55 \r
56       }\r
57       out.seek(lastLine);\r
58     }\r
59 \r
60     int seqIndex = 0;\r
61     Vector sequences = align.getSequences();\r
62 \r
63     while (seqIndex < sequences.size())\r
64     {\r
65       ArrayList ids = new ArrayList();\r
66       for (int i = 0; seqIndex < sequences.size() && i < 50; seqIndex++, i++)\r
67       {\r
68         SequenceI sequence = (SequenceI) sequences.get(seqIndex);\r
69         ids.add(sequence.getName());\r
70       }\r
71 \r
72       tryLocalCacheFirst(ids, align);\r
73 \r
74       if (ids.size() > 0)\r
75       {\r
76         StringBuffer remainingIds = new StringBuffer("uniprot:");\r
77         for (int i = 0; i < ids.size(); i++)\r
78           remainingIds.append(ids.get(i) + ";");\r
79 \r
80          EBIFetchClient ebi = new EBIFetchClient();\r
81         String[] result = ebi.fetchData(remainingIds.toString(), "xml", null);\r
82 \r
83         if(result!=null)\r
84           ReadUniprotFile(result, out, align);\r
85       }\r
86 \r
87     }\r
88 \r
89     if (out != null)\r
90     {\r
91       out.writeBytes("</UNIPROT_CACHE>\n");\r
92       out.close();\r
93     }\r
94   }catch(Exception ex){ex.printStackTrace();}\r
95 \r
96 \r
97 }\r
98 \r
99 void ReadUniprotFile(String [] result, RandomAccessFile out, AlignmentI align)\r
100 {\r
101   SequenceI sequence = null;\r
102   Vector features = null;\r
103   String type, description, status, start, end, pdb = null;\r
104 \r
105 \r
106   for (int r = 0; r < result.length; r++)\r
107   {\r
108     if(sequence==null && result[r].indexOf("<name>")>-1)\r
109     {\r
110       long filePointer = 0;\r
111 \r
112       if(out!=null)\r
113       try{\r
114         filePointer=out.getFilePointer();\r
115         out.writeBytes("<entry>\n");\r
116       }catch(Exception ex){}\r
117 \r
118       sequence = align.findName( parseElement( result[r], "<name>" , out)) ;\r
119       if(sequence==null)\r
120       {\r
121         System.out.println("Couldnt find sequence id. Suggestion is "+result[r]);\r
122 \r
123         // this entry has been suggested by ebi.\r
124         // doesn't match id in alignment file\r
125         try   { out.setLength(filePointer);  }  catch (Exception ex) {}\r
126         // now skip to next entry\r
127         while( result[r].indexOf("</entry>")==-1)\r
128           r++;\r
129       }\r
130 \r
131       features = new Vector();\r
132       type=""; start="0"; end="0"; description=""; status=""; pdb="";\r
133 \r
134     }\r
135 \r
136     if(sequence==null)\r
137       continue;\r
138 \r
139      if( result[r].indexOf("<property type=\"pdb accession\"")>-1)\r
140      {\r
141        pdb = parseValue( result[r], "value=" , out);\r
142        sequence.setPDBId(pdb);\r
143      }\r
144 \r
145      if(result[r].indexOf("feature type")>-1)\r
146      {\r
147        type = parseValue( result[r], "type=" , out);\r
148        description = parseValue( result[r], "description=" , null );\r
149        status = parseValue ( result[r], "status=", null);\r
150 \r
151        while( result[r].indexOf("position")==-1)\r
152        {\r
153            r++;  //<location>\r
154        }\r
155       // r++;\r
156        if(result[r].indexOf("begin")>-1)\r
157        {\r
158          start = parseValue( result[r], "position=" , out);\r
159          end = parseValue( result[++r], "position=" , out);\r
160        }\r
161        else\r
162        {\r
163          start = parseValue( result[r], "position=" , out);\r
164          end = parseValue(   result[r], "position=" , null);\r
165        }\r
166        int sstart = Integer.parseInt(start);\r
167        int eend = Integer.parseInt(end);\r
168        if(out!=null)\r
169          try{ out.writeBytes("</feature>\n"); }catch(Exception ex){}\r
170 \r
171 \r
172        if(sstart>=sequence.getStart() && eend<=sequence.getEnd())\r
173        {\r
174          SequenceFeature sf = new SequenceFeature(type,\r
175              sstart,\r
176              eend,\r
177              description,\r
178              status);\r
179          features.add(sf);\r
180        }\r
181      }\r
182 \r
183      if(result[r].indexOf("</entry>")>-1)\r
184      {\r
185        if(features!=null)\r
186          sequence.setSequenceFeatures( features );\r
187        features = null;\r
188        sequence = null;\r
189        if(out!=null)\r
190          try{  out.writeBytes("</entry>\n"); }catch(Exception ex){}\r
191 \r
192      }\r
193   }\r
194 \r
195   ap.RefreshPanels();\r
196 \r
197 }\r
198 \r
199 void tryLocalCacheFirst(ArrayList ids, AlignmentI align)\r
200 {\r
201   ArrayList cacheData = new ArrayList();\r
202   try{\r
203     BufferedReader in = new BufferedReader(\r
204           new FileReader(jalview.bin.Cache.getProperty("UNIPROT_CACHE")));\r
205 \r
206     // read through cache file, if the cache has sequences we're looking for\r
207     // add the lines to a new String array, Readthis new array and\r
208     // make sure we remove the ids from the list to retrieve from EBI\r
209     String data;\r
210     while( ( data=in.readLine())!=null)\r
211     {\r
212       if(data.indexOf("name")>-1)\r
213       {\r
214         String name = parseElement( data, "<name>" , null) ;\r
215         if(ids.contains( name ) )\r
216         {\r
217           cacheData.add("<entry>");\r
218           cacheData.add(data);\r
219           while( data.indexOf("</entry>")==-1)\r
220           {\r
221             data = in.readLine();\r
222             cacheData.add(data);\r
223           }\r
224           cacheData.add(data);\r
225 \r
226           ids.remove( name );\r
227         }\r
228       }\r
229     }\r
230   }\r
231   catch(Exception ex){ex.printStackTrace();}\r
232 \r
233   String [] localData = new String[cacheData.size()];\r
234   cacheData.toArray( localData );\r
235   if(localData!=null && localData.length>0)\r
236     ReadUniprotFile(localData, null, align);\r
237 }\r
238 \r
239 \r
240 String parseValue(String line, String tag, RandomAccessFile out)\r
241 {\r
242   if(out!=null)\r
243     try{  out.writeBytes(line+"\n"); }catch(Exception ex){}\r
244 \r
245 \r
246   int index = line.indexOf(tag)+tag.length()+1;\r
247   if(index==tag.length())\r
248     return "";\r
249 \r
250   return line.substring( index, line.indexOf("\"", index+1) );\r
251 }\r
252 \r
253 \r
254 String parseElement(String line, String tag, RandomAccessFile out)\r
255 {\r
256   if (out != null)\r
257     try\r
258     {\r
259       out.writeBytes(line + "\n");\r
260     }\r
261     catch (Exception ex)\r
262     {}\r
263 \r
264   int index = line.indexOf(tag) + tag.length();\r
265   return line.substring(index, line.indexOf("</"));\r
266 }\r
267 \r
268 \r
269 }\r