JAL-1807 explicit imports (jalview.ws.*)
[jalview.git] / src / jalview / ws / rest / HttpResultSet.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.ws.rest;
22
23 import jalview.bin.Cache;
24 import jalview.io.FileParse;
25 import jalview.io.packed.DataProvider;
26 import jalview.io.packed.DataProvider.JvDataType;
27 import jalview.io.packed.JalviewDataset;
28 import jalview.io.packed.ParsePackedSet;
29 import jalview.io.packed.SimpleDataProvider;
30 import jalview.util.MessageManager;
31 import jalview.ws.io.mime.JalviewMimeContentHandler;
32
33 import java.io.BufferedReader;
34 import java.io.IOException;
35 import java.io.InputStreamReader;
36 import java.io.UnsupportedEncodingException;
37 import java.util.ArrayList;
38 import java.util.List;
39
40 import org.apache.http.HttpEntity;
41 import org.apache.http.HttpResponse;
42 import org.apache.http.client.methods.HttpRequestBase;
43 import org.apache.http.entity.mime.MultipartEntity;
44 import org.apache.james.mime4j.MimeException;
45 import org.apache.james.mime4j.parser.MimeStreamParser;
46
47 /**
48  * data source instantiated from the response of an httpclient request.
49  * 
50  * @author JimP
51  * 
52  */
53
54 public class HttpResultSet extends FileParse
55 {
56
57   private HttpRequestBase cachedRequest;
58
59   /**
60    * when set, indicates that en can be recreated by repeating the HttpRequest
61    * in cachedRequest
62    */
63   boolean repeatable = false;
64
65   /**
66    * response that is to be parsed as jalview input data
67    */
68   private HttpEntity en = null;
69
70   /**
71    * (sub)job that produced this result set.
72    */
73   private RestJob restJob;
74
75   public HttpResultSet(RestJob rj, HttpResponse con, HttpRequestBase req)
76           throws IOException
77   {
78     super();
79     setDataName(rj.getJobId() + " Part " + rj.getJobnum());
80     restJob = rj;
81     cachedRequest = req;
82     initDataSource(con);
83   }
84
85   /**
86    * construct a set of dataproviders to parse a result set from this service
87    * 
88    * @param resSet
89    * @return
90    */
91   public List<DataProvider> createResultDataProviders()
92   {
93     List<DataProvider> dp = new ArrayList<DataProvider>();
94     for (JvDataType type : restJob.rsd.getResultDataTypes())
95     {
96       dp.add(new SimpleDataProvider(type, this, null));
97     }
98     return dp;
99   }
100
101   /**
102    * parses the results of the service output.
103    * 
104    * @return the result of ParsePackedSet.getAlignment()
105    * @throws Exception
106    * @throws Error
107    */
108   public Object[] parseResultSet() throws Exception, Error
109   {
110     List<DataProvider> dp = new ArrayList<DataProvider>();
111     Object[] results = null;
112
113     if (en == null)
114     {
115       throw new Error(MessageManager.getString("error.implementation_error_need_to_have_httpresponse"));
116     }
117     JalviewDataset ds = restJob.newJalviewDataset();
118     // Decide how we deal with content.
119     if (en instanceof MultipartEntity)
120     {
121       // Multipart messages should be properly typed, so we parse them as we go.
122       MultipartEntity mpe = (MultipartEntity) en;
123       // multipart
124       JalviewMimeContentHandler handler = new JalviewMimeContentHandler(ds);
125       MimeStreamParser parser = new MimeStreamParser();
126       parser.setContentHandler(handler);
127       try
128       {
129         parser.parse(mpe.getContent());
130       } catch (MimeException me)
131       {
132         error = true;
133         errormessage = "Couldn't parse message from web service.";
134         Cache.log.warn("Failed to parse MIME multipart content", me);
135         en.consumeContent();
136       }
137       return new ParsePackedSet().getAlignment(ds,
138               handler.getJalviewDataProviders());
139     }
140     else
141     {
142       // Need to use hints from rest service description.
143       dp = createResultDataProviders();
144       ParsePackedSet pps = new ParsePackedSet();
145       return pps.getAlignment(ds, dp);
146     }
147   }
148
149   private void initDataSource(HttpResponse con) throws IOException
150   {
151     en = con.getEntity();
152     repeatable = en.isRepeatable();
153
154     if (!(en instanceof MultipartEntity))
155     {
156       // assume content is simple text stream that can be read from
157       String enc = (en.getContentEncoding() == null) ? null : en
158               .getContentEncoding().getValue();
159       if (en.getContentType() != null)
160       {
161         Cache.log.debug("Result Type: " + en.getContentType().toString());
162       }
163       else
164       {
165         Cache.log.debug("No Result Type Specified.");
166       }
167       if (enc == null || enc.length() < 1)
168       {
169         Cache.log.debug("Assuming 'Default' Result Encoding.");
170       }
171       else
172       {
173         Cache.log.debug("Result Encoded as : " + enc);
174       }
175       // attempt to identify file and construct an appropriate DataSource
176       // identifier for it.
177       // try to parse
178       // Mime-Multipart or single content type will be expected.
179       // if (enc.equals(org.apache.http.client.utils.)))
180       InputStreamReader br = null;
181       try
182       {
183         br = (enc != null) ? new InputStreamReader(en.getContent(), enc)
184                 : new InputStreamReader(en.getContent());
185       } catch (UnsupportedEncodingException e)
186       {
187         Cache.log.error("Can't handle encoding '" + enc
188                 + "' for response from webservice.", e);
189         en.consumeContent();
190         error = true;
191         errormessage = "Can't handle encoding for response from webservice";
192         return;
193       }
194       if (br != null)
195       {
196         dataIn = new BufferedReader(br);
197         error = false;
198       }
199     }
200   }
201
202   @Override
203   protected void finalize() throws Throwable
204   {
205     dataIn = null;
206     cachedRequest = null;
207     try
208     {
209       if (en != null)
210       {
211         en.consumeContent();
212       }
213     } catch (Exception e)
214     {
215     } catch (Error ex)
216     {
217     }
218     super.finalize();
219   }
220
221   /**
222    * 
223    * @return the URL that this result set read data from.
224    */
225   public String getUrl()
226   {
227     try
228     {
229       return cachedRequest.getURI().toURL().toString();
230     } catch (Exception x)
231     {
232       x.printStackTrace();
233       return null;
234     }
235   }
236
237 }