pdb xrefs added as dbrefs and as PDB file links
[jalview.git] / src / jalview / ws / dbsources / Uniprot.java
1 /**
2  * 
3  */
4 package jalview.ws.dbsources;
5
6 import java.io.File;
7 import java.io.FileReader;
8 import java.io.IOException;
9 import java.util.Enumeration;
10 import java.util.Hashtable;
11 import java.util.Vector;
12
13 import org.exolab.castor.xml.Unmarshaller;
14
15 import com.stevesoft.pat.Regex;
16
17 import jalview.datamodel.Alignment;
18 import jalview.datamodel.AlignmentI;
19 import jalview.datamodel.DBRefEntry;
20 import jalview.datamodel.DBRefSource;
21 import jalview.datamodel.PDBEntry;
22 import jalview.datamodel.SequenceFeature;
23 import jalview.datamodel.SequenceI;
24 import jalview.datamodel.UniprotEntry;
25 import jalview.datamodel.UniprotFile;
26 import jalview.io.FormatAdapter;
27 import jalview.io.IdentifyFile;
28 import jalview.ws.DBRefFetcher;
29 import jalview.ws.ebi.EBIFetchClient;
30 import jalview.ws.seqfetcher.DbSourceProxy;
31 import jalview.ws.seqfetcher.DbSourceProxyImpl;
32
33 /**
34  * @author JimP
35  * 
36  */
37 public class Uniprot extends DbSourceProxyImpl implements DbSourceProxy
38 {
39   public Uniprot() {
40     super();
41     addDbSourceProperty(DBRefSource.SEQDB, DBRefSource.SEQDB);
42     addDbSourceProperty(DBRefSource.PROTSEQDB);
43 //    addDbSourceProperty(DBRefSource.MULTIACC, new Integer(50));
44   }
45
46   /*
47    * (non-Javadoc)
48    * 
49    * @see jalview.ws.DbSourceProxy#getAccessionSeparator()
50    */
51   public String getAccessionSeparator()
52   {
53     return null; // ";";
54   }
55
56   /*
57    * (non-Javadoc)
58    * 
59    * @see jalview.ws.DbSourceProxy#getAccessionValidator()
60    */
61   public Regex getAccessionValidator()
62   {
63     return null;
64   }
65
66   /*
67    * (non-Javadoc)
68    * 
69    * @see jalview.ws.DbSourceProxy#getDbSource()
70    */
71   public String getDbSource()
72   {
73     return DBRefSource.UNIPROT;
74   }
75
76   /*
77    * (non-Javadoc)
78    * 
79    * @see jalview.ws.DbSourceProxy#getDbVersion()
80    */
81   public String getDbVersion()
82   {
83     return "0"; // we really don't know what version we're on.
84   }
85
86   private EBIFetchClient ebi = null;
87
88   public Vector getUniprotEntries(File file)
89   {
90     UniprotFile uni = new UniprotFile();
91     try
92     {
93       // 1. Load the mapping information from the file
94       org.exolab.castor.mapping.Mapping map = new org.exolab.castor.mapping.Mapping(uni.getClass().getClassLoader());
95       java.net.URL url = getClass().getResource("/uniprot_mapping.xml");
96       map.loadMapping(url);
97
98       // 2. Unmarshal the data
99       Unmarshaller unmar = new Unmarshaller(uni);
100       unmar.setIgnoreExtraElements(true);
101       unmar.setMapping(map);
102
103       uni = (UniprotFile) unmar.unmarshal(new FileReader(file));
104     }
105     catch (Exception e)
106     {
107       System.out.println("Error getUniprotEntries() " + e);
108     }
109
110     return uni.getUniprotEntries();
111   }
112
113   /*
114    * (non-Javadoc)
115    * 
116    * @see jalview.ws.DbSourceProxy#getSequenceRecords(java.lang.String[])
117    */
118   public AlignmentI getSequenceRecords(String queries) throws Exception
119   {
120     startQuery();
121     try
122     {
123       Alignment al=null;
124       ebi = new EBIFetchClient();
125       StringBuffer result=new StringBuffer();
126       // uniprotxml parameter required since december 2007
127       File file = ebi.fetchDataAsFile("uniprot:" + queries, "uniprotxml", null);
128       Vector entries = getUniprotEntries(file);
129
130       if (entries != null)
131       {
132         // First, make the new sequences
133         Enumeration en = entries.elements();
134         while (en.hasMoreElements())
135         {
136           UniprotEntry entry = (UniprotEntry) en.nextElement();
137
138           StringBuffer name = new StringBuffer(">UniProt/Swiss-Prot");
139           Enumeration en2 = entry.getAccession().elements();
140           while (en2.hasMoreElements())
141           {
142             name.append("|");
143             name.append(en2.nextElement());
144           }
145           en2 = entry.getName().elements();
146           while (en2.hasMoreElements())
147           {
148             name.append("|");
149             name.append(en2.nextElement());
150           }
151
152           if (entry.getProtein()!=null && entry.getProtein().getName()!=null)
153           {
154               for (int nm=0,nmSize=entry.getProtein().getName().size(); nm<nmSize;nm++)
155               {
156                 name.append(" " + entry.getProtein().getName().elementAt(nm));
157               }
158           }
159
160           result.append(name + "\n"
161                   + entry.getUniprotSequence().getContent() + "\n");
162
163         }
164
165         // Then read in the features and apply them to the dataset
166         al = parseResult(result.toString());
167         if (al!=null)
168         {
169           // Decorate the alignment with database entries.
170           addUniprotXrefs(al, entries);
171         } else {
172           results = result;
173         }
174       }
175       stopQuery();
176       return al;
177     } catch (Exception e)
178     {
179       stopQuery();
180       throw(e);
181     }
182   }
183
184   /**
185    * add an ordered set of UniprotEntry objects to an ordered set of seuqences.
186    * 
187    * @param al -
188    *          a sequence of n sequences
189    * @param entries
190    *          a seuqence of n uniprot entries to be analysed.
191    */
192   public void addUniprotXrefs(Alignment al, Vector entries)
193   {
194     for (int i = 0; i < entries.size(); i++)
195     {
196       UniprotEntry entry = (UniprotEntry) entries.elementAt(i);
197       Enumeration e = entry.getDbReference().elements();
198       Vector onlyPdbEntries = new Vector();
199       Vector dbxrefs = new Vector();
200       while (e.hasMoreElements())
201       {
202         PDBEntry pdb = (PDBEntry) e.nextElement();
203         DBRefEntry dbr = new DBRefEntry();
204         dbr.setSource(pdb.getType());
205         dbr.setAccessionId(pdb.getId());
206         dbr.setVersion(DBRefSource.UNIPROT+":"+getDbVersion());
207         dbxrefs.addElement(dbr);
208         if (!pdb.getType().equals("PDB"))
209         {
210           continue;
211         }
212         
213         onlyPdbEntries.addElement(pdb);
214       }
215       SequenceI sq = al.getSequenceAt(i);
216       while (sq.getDatasetSequence()!=null)
217       {
218         sq = sq.getDatasetSequence();
219       }
220
221       Enumeration en2 = entry.getAccession().elements();
222       while (en2.hasMoreElements())
223       {
224         // we always add as uniprot if we retrieved from uniprot or uniprot name
225         sq.addDBRef(
226                 new DBRefEntry(DBRefSource.UNIPROT, getDbVersion(), en2.nextElement()
227                         .toString()));
228       }
229       en2 = dbxrefs.elements();
230       while (en2.hasMoreElements())
231       {
232      // we always add as uniprot if we retrieved from uniprot or uniprot name
233         sq.addDBRef((DBRefEntry) en2.nextElement());
234                     
235       }
236       sq.setPDBId(onlyPdbEntries);
237       if (entry.getFeature() != null)
238       {
239         e = entry.getFeature().elements();
240         while (e.hasMoreElements())
241         {
242           SequenceFeature sf = (SequenceFeature) e.nextElement();
243           sf.setFeatureGroup("Uniprot");
244           sq.addSequenceFeature(sf);
245         }
246       }
247     }
248   }
249
250   /*
251    * (non-Javadoc)
252    * 
253    * @see jalview.ws.DbSourceProxy#isValidReference(java.lang.String)
254    */
255   public boolean isValidReference(String accession)
256   {
257     return true;
258   }
259   /**
260    * return LDHA_CHICK uniprot entry
261    */
262   public String getTestQuery()
263   {
264     return "P00340";
265   }
266   public String getDbName()
267   {
268     return "Uniprot"; // getDbSource();
269   }
270 }