JAL-1620 version bump and release notes
[jalview.git] / src / jalview / ws / dbsources / Uniprot.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2b1)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.ws.dbsources;
22
23 import java.io.File;
24 import java.io.FileReader;
25 import java.util.Enumeration;
26 import java.util.Vector;
27
28 import org.exolab.castor.xml.Unmarshaller;
29
30 import com.stevesoft.pat.Regex;
31
32 import jalview.datamodel.Alignment;
33 import jalview.datamodel.AlignmentI;
34 import jalview.datamodel.DBRefEntry;
35 import jalview.datamodel.DBRefSource;
36 import jalview.datamodel.PDBEntry;
37 import jalview.datamodel.SequenceFeature;
38 import jalview.datamodel.SequenceI;
39 import jalview.datamodel.UniprotEntry;
40 import jalview.datamodel.UniprotFile;
41 import jalview.ws.ebi.EBIFetchClient;
42 import jalview.ws.seqfetcher.DbSourceProxy;
43 import jalview.ws.seqfetcher.DbSourceProxyImpl;
44
45 /**
46  * @author JimP
47  * 
48  */
49 public class Uniprot extends DbSourceProxyImpl implements DbSourceProxy
50 {
51   public Uniprot()
52   {
53     super();
54     addDbSourceProperty(DBRefSource.SEQDB, DBRefSource.SEQDB);
55     addDbSourceProperty(DBRefSource.PROTSEQDB);
56     // addDbSourceProperty(DBRefSource.MULTIACC, new Integer(50));
57   }
58
59   /*
60    * (non-Javadoc)
61    * 
62    * @see jalview.ws.DbSourceProxy#getAccessionSeparator()
63    */
64   public String getAccessionSeparator()
65   {
66     return null; // ";";
67   }
68
69   /*
70    * (non-Javadoc)
71    * 
72    * @see jalview.ws.DbSourceProxy#getAccessionValidator()
73    */
74   public Regex getAccessionValidator()
75   {
76     return new Regex("([A-Z]+[0-9]+[A-Z0-9]+|[A-Z0-9]+_[A-Z0-9]+)");
77   }
78
79   /*
80    * (non-Javadoc)
81    * 
82    * @see jalview.ws.DbSourceProxy#getDbSource()
83    */
84   public String getDbSource()
85   {
86     return DBRefSource.UNIPROT;
87   }
88
89   /*
90    * (non-Javadoc)
91    * 
92    * @see jalview.ws.DbSourceProxy#getDbVersion()
93    */
94   public String getDbVersion()
95   {
96     return "0"; // we really don't know what version we're on.
97   }
98
99   private EBIFetchClient ebi = null;
100
101   private static org.exolab.castor.mapping.Mapping map;
102
103   public Vector getUniprotEntries(File file)
104   {
105     UniprotFile uni = new UniprotFile();
106     try
107     {
108       if (map == null)
109       {
110         // 1. Load the mapping information from the file
111         map = new org.exolab.castor.mapping.Mapping(uni.getClass()
112                 .getClassLoader());
113         java.net.URL url = getClass().getResource("/uniprot_mapping.xml");
114         map.loadMapping(url);
115       }
116
117       // 2. Unmarshal the data
118       Unmarshaller unmar = new Unmarshaller(uni);
119       unmar.setIgnoreExtraElements(true);
120       unmar.setMapping(map);
121       if (file != null)
122       {
123         uni = (UniprotFile) unmar.unmarshal(new FileReader(file));
124       }
125     } catch (Exception e)
126     {
127       System.out.println("Error getUniprotEntries() " + e);
128     }
129
130     return uni.getUniprotEntries();
131   }
132
133   /*
134    * (non-Javadoc)
135    * 
136    * @see jalview.ws.DbSourceProxy#getSequenceRecords(java.lang.String[])
137    */
138   public AlignmentI getSequenceRecords(String queries) throws Exception
139   {
140     startQuery();
141     try
142     {
143       queries = queries.toUpperCase().replaceAll(
144               "(UNIPROT\\|?|UNIPROT_|UNIREF\\d+_|UNIREF\\d+\\|?)", "");
145       Alignment al = null;
146       ebi = new EBIFetchClient();
147       StringBuffer result = new StringBuffer();
148       // uniprotxml parameter required since december 2007
149       // uniprotkb dbname changed introduced december 2008
150       File file = ebi.fetchDataAsFile("uniprotkb:" + queries, "uniprotxml",
151               null);
152       Vector entries = getUniprotEntries(file);
153
154       if (entries != null)
155       {
156         // First, make the new sequences
157         Enumeration en = entries.elements();
158         while (en.hasMoreElements())
159         {
160           UniprotEntry entry = (UniprotEntry) en.nextElement();
161
162           StringBuffer name = new StringBuffer(">UniProt/Swiss-Prot");
163           Enumeration en2 = entry.getAccession().elements();
164           while (en2.hasMoreElements())
165           {
166             name.append("|");
167             name.append(en2.nextElement());
168           }
169           en2 = entry.getName().elements();
170           while (en2.hasMoreElements())
171           {
172             name.append("|");
173             name.append(en2.nextElement());
174           }
175
176           if (entry.getProtein() != null
177                   && entry.getProtein().getName() != null)
178           {
179             for (int nm = 0, nmSize = entry.getProtein().getName().size(); nm < nmSize; nm++)
180             {
181               name.append(" " + entry.getProtein().getName().elementAt(nm));
182             }
183           }
184
185           result.append(name + "\n"
186                   + entry.getUniprotSequence().getContent() + "\n");
187
188         }
189
190         // Then read in the features and apply them to the dataset
191         al = parseResult(result.toString());
192         if (al != null)
193         {
194           // Decorate the alignment with database entries.
195           addUniprotXrefs(al, entries);
196         }
197         else
198         {
199           results = result;
200         }
201       }
202       stopQuery();
203       return al;
204     } catch (Exception e)
205     {
206       stopQuery();
207       throw (e);
208     }
209   }
210
211   /**
212    * add an ordered set of UniprotEntry objects to an ordered set of seuqences.
213    * 
214    * @param al
215    *          - a sequence of n sequences
216    * @param entries
217    *          a seuqence of n uniprot entries to be analysed.
218    */
219   public void addUniprotXrefs(Alignment al, Vector entries)
220   {
221     for (int i = 0; i < entries.size(); i++)
222     {
223       UniprotEntry entry = (UniprotEntry) entries.elementAt(i);
224       Enumeration e = entry.getDbReference().elements();
225       Vector onlyPdbEntries = new Vector();
226       Vector dbxrefs = new Vector();
227       while (e.hasMoreElements())
228       {
229         PDBEntry pdb = (PDBEntry) e.nextElement();
230         DBRefEntry dbr = new DBRefEntry();
231         dbr.setSource(pdb.getType());
232         dbr.setAccessionId(pdb.getId());
233         dbr.setVersion(DBRefSource.UNIPROT + ":" + getDbVersion());
234         dbxrefs.addElement(dbr);
235         if (!pdb.getType().equals("PDB"))
236         {
237           continue;
238         }
239
240         onlyPdbEntries.addElement(pdb);
241       }
242       SequenceI sq = al.getSequenceAt(i);
243       while (sq.getDatasetSequence() != null)
244       {
245         sq = sq.getDatasetSequence();
246       }
247
248       Enumeration en2 = entry.getAccession().elements();
249       while (en2.hasMoreElements())
250       {
251         // we always add as uniprot if we retrieved from uniprot or uniprot name
252         sq.addDBRef(new DBRefEntry(DBRefSource.UNIPROT, getDbVersion(), en2
253                 .nextElement().toString()));
254       }
255       en2 = dbxrefs.elements();
256       while (en2.hasMoreElements())
257       {
258         // we always add as uniprot if we retrieved from uniprot or uniprot name
259         sq.addDBRef((DBRefEntry) en2.nextElement());
260
261       }
262       sq.setPDBId(onlyPdbEntries);
263       if (entry.getFeature() != null)
264       {
265         e = entry.getFeature().elements();
266         while (e.hasMoreElements())
267         {
268           SequenceFeature sf = (SequenceFeature) e.nextElement();
269           sf.setFeatureGroup("Uniprot");
270           sq.addSequenceFeature(sf);
271         }
272       }
273     }
274   }
275
276   /*
277    * (non-Javadoc)
278    * 
279    * @see jalview.ws.DbSourceProxy#isValidReference(java.lang.String)
280    */
281   public boolean isValidReference(String accession)
282   {
283     // TODO: make the following a standard validator
284     return (accession == null || accession.length() < 2) ? false
285             : getAccessionValidator().search(accession);
286   }
287
288   /**
289    * return LDHA_CHICK uniprot entry
290    */
291   public String getTestQuery()
292   {
293     return "P00340";
294   }
295
296   public String getDbName()
297   {
298     return "Uniprot"; // getDbSource();
299   }
300
301   @Override
302   public int getTier()
303   {
304     return 0;
305   }
306 }