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