9a4af6294bbcb0f2360eebb23f15d152ec1993cd
[jalview.git] / src / jalview / io / packed / ParsePackedSet.java
1 package jalview.io.packed;
2
3 import jalview.datamodel.AlignmentI;
4 import jalview.io.AppletFormatAdapter;
5 import jalview.io.FileParse;
6 import jalview.io.FormatAdapter;
7 import jalview.io.IdentifyFile;
8 import jalview.io.packed.DataProvider.JvDataType;
9
10 import java.io.BufferedReader;
11 import java.io.IOException;
12 import java.util.ArrayList;
13 import java.util.Hashtable;
14 import java.util.List;
15
16 public class ParsePackedSet
17 {
18
19   /**
20    * return results as a series of jalview.datamodel objects suitable for
21    * display
22    * 
23    * @param context
24    *          - context which is updated with new data
25    * @param files
26    *          - source data
27    * @return list of data objects added to context
28    * @throws Exception
29    */
30   public Object[] getAlignment(JalviewDataset context,
31           Iterable<DataProvider> files) throws Exception
32   {
33     List<Object> rslt = new ArrayList<Object>();
34     if (context == null)
35     {
36       context = new JalviewDataset();
37     }
38     boolean deuniquify = false;
39     for (DataProvider dta : files)
40     {
41       Exception exerror = null;
42       String errmsg = null;
43       FileParse src = dta.getDataSource();
44       if (dta.getType().equals(DataProvider.JvDataType.ALIGNMENT))
45       {
46         String fmt = null;
47         try
48         {
49           fmt = new IdentifyFile().Identify(src, false);
50         } catch (Exception ex)
51         {
52           exerror = ex;
53           errmsg = "Couldn't identify alignment format.";
54         }
55
56         if (fmt != null)
57         {
58           if (!FormatAdapter.isValidIOFormat(fmt, false))
59           {
60             errmsg = fmt;
61             exerror = null;
62           }
63           else
64           {
65             // parse the alignment
66             AlignmentI al = null;
67             try
68             {
69               al = new FormatAdapter().readFromFile(src, fmt);
70             } catch (Exception e)
71             {
72               errmsg = "Failed to parse alignment from result set";
73               exerror = e;
74             }
75             if (al != null)
76             {
77               // deuniquify and construct/merge additional dataset entries if
78               // necessary.
79               context.addAlignment(al);
80               context.updateSetModified(true);
81               rslt.add(al);
82               deuniquify = true;
83             }
84           }
85         }
86       }
87       if (dta.getType().equals(JvDataType.ANNOTATION))
88       {
89         if (!context.hasAlignments())
90         {
91           errmsg = "No alignment or sequence dataset to associate annotation with.";
92           // could duplicate the dataset reference here as default behaviour for
93           // sequence associated annotation ?
94         }
95         try
96         {
97           BufferedReader br;
98           if (src.getReader() instanceof BufferedReader)
99           {
100             br = (BufferedReader) src.getReader();
101           }
102           else
103           {
104             br = new BufferedReader(src.getReader());
105           }
106           if (new jalview.io.AnnotationFile()
107                   .parseAnnotationFrom(context.getLastAlignment(), br))
108           {
109             context.updateSetModified(true);
110           } else {
111             errmsg = "Annotation file contained no data.";
112           }
113
114         } catch (Exception e)
115         {
116           errmsg = ((errmsg == null) ? "" : errmsg)
117                   + "Failed to parse the annotation file associated with the alignment.";
118           exerror = e;
119         }
120       }
121       if (dta.getType().equals(JvDataType.SEQASSOCATED))
122       {
123         if (!context.hasSequenceAssoc())
124         {
125           errmsg = "No sequence to associate data with.";
126
127         }
128         errmsg = "parsing of sequence associated data is not implemented";
129         exerror = new Exception(errmsg);
130       }
131       if (dta.getType().equals(JvDataType.FEATURES))
132       {
133         // check the context has a place to store feature rendering definitions,
134         // if not, create one.
135         if (context.featureColours == null)
136         {
137           context.featureColours = new Hashtable();
138         }
139         try
140         {
141           jalview.io.FeaturesFile ff = new jalview.io.FeaturesFile(src);
142           context.updateSetModified(ff.parse(context.getLastAlignment(), 
143                   context.featureColours, false, context.relaxedIdMatching));
144         } catch (Exception e)
145         {
146           errmsg = ("Failed to parse the Features file associated with the alignment.");
147           exerror = e;
148         }
149       }
150       if (dta.getType().equals(JvDataType.TREE))
151       {
152         try
153         {
154           jalview.io.NewickFile nf = new jalview.io.NewickFile(src);
155           if (!nf.isValid())
156           {
157             nf.close();
158             nf = null;
159           }
160           else
161           {
162             // do association to current alignment.
163
164             context.addTreeFromFile(nf);
165             rslt.add(nf);
166             context.updateSetModified(true);
167           }
168         } catch (Exception e)
169         {
170           errmsg = ("Failed to parse the treeFile associated with the result.");
171           exerror = e;
172         }
173
174       }
175       if (exerror!=null)
176       {
177         if (errmsg!=null && errmsg.length()>0)
178         {
179           throw new IOException(errmsg,exerror);
180         } else {
181           throw new IOException(errmsg,exerror);
182         }
183       } else {
184       if (errmsg!=null && errmsg.length()>0)
185       {
186         throw new IOException(errmsg);
187       }
188       }
189     }
190     if (deuniquify)
191     {
192       context.getLastAlignmentSet().deuniquifyAlignment();
193     }
194     return rslt.toArray();
195   }
196
197   /**
198    * simple command line test. Arguments should be one or more pairs of
199    * <DataProvider.JvDataType> <Filename> arguments. The routine will attempt to
200    * read each source in turn, and report what kind of Jalview datamodel objects
201    * would be created.
202    * 
203    * @param args
204    */
205   public static void main(String args[])
206   {
207     // make data providers from the set of keys/files
208     int i = 0;
209     List<DataProvider> dp = new ArrayList<DataProvider>();
210     while ((i + 1) < args.length)
211     {
212       String type = args[i++];
213       final String file = args[i++];
214       final JvDataType jtype = DataProvider.JvDataType.valueOf(type
215               .toUpperCase());
216       if (jtype != null)
217       {
218         final FileParse fp;
219         try
220         {
221           fp = new FileParse(file, AppletFormatAdapter.checkProtocol(file));
222         } catch (Exception e)
223         {
224           System.err.println("Couldn't handle datasource of type " + jtype
225                   + " using URI " + file);
226           e.printStackTrace();
227           return;
228         }
229         dp.add(new SimpleDataProvider(jtype, fp, null));
230       }
231       else
232       {
233         System.out.println("Couldn't parse source type token '"
234                 + type.toUpperCase() + "'");
235       }
236     }
237     if (i < args.length)
238     {
239       System.out.print("** WARNING\nIgnoring unused arguments:\n");
240       while (i < args.length)
241       {
242         System.out.print(" " + args[i]);
243       }
244       System.out.print("\n");
245
246     }
247     System.out.println("Now trying to parse set:");
248     JalviewDataset context;
249     Object[] newdm;
250     ParsePackedSet pps;
251     try
252     {
253       newdm = (pps = new ParsePackedSet()).getAlignment(
254               context = new JalviewDataset(), dp);
255     } catch (Exception e)
256     {
257       System.out.println("Test failed for these arguments.\n");
258       e.printStackTrace(System.out);
259       return;
260     }
261     if (newdm != null)
262     {
263       for (Object o : newdm)
264       {
265         System.out.println("Will need to create an " + o.getClass());
266       }
267
268       // now test uniquify/deuniquify stuff
269       // uniquify alignment and write alignment, annotation, features, and trees
270       // to buffers.
271       // import with deuniquify info, and compare results to input.
272
273     } else {
274       if (context.getLastAlignmentSet().isModified())
275       {
276         System.err.println("Initial alignment set was modified and any associated views should be updated.");
277       }
278     }
279   }
280 }