always provide reference to hashtable so feature settings can be stored
[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               rslt.add(al);
80               deuniquify = true;
81             }
82           }
83         }
84       }
85       if (dta.getType().equals(JvDataType.ANNOTATION))
86       {
87         if (!context.hasAlignments())
88         {
89           errmsg = "No alignment or sequence dataset to associate annotation with.";
90           // could duplicate the dataset reference here as default behaviour for
91           // sequence associated annotation ?
92         }
93         try
94         {
95           BufferedReader br;
96           if (src.getReader() instanceof BufferedReader)
97           {
98             br = (BufferedReader) src.getReader();
99           }
100           else
101           {
102             br = new BufferedReader(src.getReader());
103           }
104           new jalview.io.AnnotationFile().parseAnnotationFrom(
105                   context.getLastAlignment(), br);
106
107         } catch (Exception e)
108         {
109           errmsg = ((errmsg == null) ? "" : errmsg)
110                   + "Failed to parse the annotation file associated with the alignment.";
111           exerror = e;
112         }
113       }
114       if (dta.getType().equals(JvDataType.SEQASSOCATED))
115       {
116         if (!context.hasSequenceAssoc())
117         {
118           errmsg = "No sequence to associate data with.";
119
120         }
121         errmsg = "parsing of sequence associated data is not implemented";
122         exerror = new Exception(errmsg);
123       }
124       if (dta.getType().equals(JvDataType.FEATURES))
125       {
126         // check the context has a place to store feature rendering definitions, if not, create one.
127         if (context.featureColours==null)
128         {
129           context.featureColours = new Hashtable();
130         }
131         try
132         {
133           jalview.io.FeaturesFile ff = new jalview.io.FeaturesFile(src);
134           ff.parse(context.getLastAlignment(), context.featureColours,
135                   false);
136         } catch (Exception e)
137         {
138           errmsg = ("Failed to parse the Features file associated with the alignment.");
139           exerror = e;
140         }
141       }
142       if (dta.getType().equals(JvDataType.TREE))
143       {
144         try
145         {
146           jalview.io.NewickFile nf = new jalview.io.NewickFile(src);
147           if (!nf.isValid())
148           {
149             nf.close();
150             nf = null;
151           }
152           else
153           {
154             // do association to current alignment.
155
156             context.addTreeFromFile(nf);
157             rslt.add(nf);
158           }
159         } catch (Exception e)
160         {
161           errmsg = ("Failed to parse the treeFile associated with the result.");
162           exerror = e;
163         }
164
165       }
166
167     }
168     if (deuniquify)
169     {
170       context.getLastAlignmentSet().deuniquifyAlignment();
171     }
172     return rslt.toArray();
173   }
174
175   /**
176    * simple command line test. Arguments should be one or more pairs of
177    * <DataProvider.JvDataType> <Filename> arguments. The routine will attempt to
178    * read each source in turn, and report what kind of Jalview datamodel objects
179    * would be created.
180    * 
181    * @param args
182    */
183   public static void main(String args[])
184   {
185     // make data providers from the set of keys/files
186     int i = 0;
187     List<DataProvider> dp = new ArrayList<DataProvider>();
188     while ((i + 1) < args.length)
189     {
190       String type = args[i++];
191       final String file = args[i++];
192       final JvDataType jtype = DataProvider.JvDataType.valueOf(type
193               .toUpperCase());
194       if (jtype != null)
195       {
196         final FileParse fp;
197         try
198         {
199           fp = new FileParse(file, AppletFormatAdapter.checkProtocol(file));
200         } catch (Exception e)
201         {
202           System.err.println("Couldn't handle datasource of type " + jtype
203                   + " using URI " + file);
204           e.printStackTrace();
205           return;
206         }
207         dp.add(new SimpleDataProvider(jtype, fp, null));
208       }
209       else
210       {
211         System.out.println("Couldn't parse source type token '"
212                 + type.toUpperCase() + "'");
213       }
214     }
215     if (i < args.length)
216     {
217       System.out.print("** WARNING\nIgnoring unused arguments:\n");
218       while (i < args.length)
219       {
220         System.out.print(" " + args[i]);
221       }
222       System.out.print("\n");
223
224     }
225     System.out.println("Now trying to parse set:");
226     JalviewDataset context;
227     Object[] newdm;
228     ParsePackedSet pps;
229     try
230     {
231       newdm = (pps = new ParsePackedSet()).getAlignment(
232               context = new JalviewDataset(), dp);
233     } catch (Exception e)
234     {
235       System.out.println("Test failed for these arguments.\n");
236       e.printStackTrace(System.out);
237       return;
238     }
239     if (newdm != null)
240     {
241       for (Object o : newdm)
242       {
243         System.out.println("Will need to create an " + o.getClass());
244       }
245
246       // now test uniquify/deuniquify stuff
247       // uniquify alignment and write alignment, annotation, features, and trees
248       // to buffers.
249       // import with deuniquify info, and compare results to input.
250
251     }
252   }
253 }