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