View Javadoc

1   /*$Id: VizierQuerierPlugin.java,v 1.13 2004/11/22 14:43:21 jdt Exp $
2    * Created on 13-Nov-2003
3    *
4    * Copyright (C) AstroGrid. All rights reserved.
5    *
6    * This software is published under the terms of the AstroGrid
7    * Software License version 1.2, a copy of which has been included
8    * with this distribution in the LICENSE.txt file.
9    *
10   **/
11  package org.astrogrid.datacenter.impl.cds;
12  
13  import java.io.IOException;
14  import java.io.StringWriter;
15  import java.net.URL;
16  import java.util.Hashtable;
17  import javax.xml.parsers.ParserConfigurationException;
18  import javax.xml.rpc.ServiceException;
19  import org.astrogrid.community.Account;
20  import org.astrogrid.datacenter.delegate.DatacenterException;
21  import org.astrogrid.datacenter.impl.cds.generated.vizier.VizieR;
22  import org.astrogrid.datacenter.impl.cds.generated.vizier.VizieRService;
23  import org.astrogrid.datacenter.impl.cds.generated.vizier.VizieRServiceLocator;
24  import org.astrogrid.datacenter.impl.cds.vizier.VizierUnit;
25  import org.astrogrid.datacenter.impl.cds.vizier.VizierWavelength;
26  import org.astrogrid.datacenter.queriers.DefaultPlugin;
27  import org.astrogrid.datacenter.queriers.Querier;
28  import org.astrogrid.datacenter.queriers.QueryResults;
29  import org.astrogrid.datacenter.queriers.VotableDomResults;
30  import org.astrogrid.datacenter.queriers.VotableInResults;
31  import org.astrogrid.datacenter.queriers.sql.RdbmsResourceReader;
32  import org.astrogrid.datacenter.queriers.status.QuerierQuerying;
33  import org.astrogrid.datacenter.query.Query;
34  import org.astrogrid.datacenter.returns.ReturnTable;
35  import org.astrogrid.slinger.targets.TargetMaker;
36  import org.astrogrid.util.DomHelper;
37  import org.xml.sax.SAXException;
38  
39  /*** Datacenter querier SPI that performs queries against CDS Vizier webservice.
40   * <p>
41   * The Vizier SOAP services take the following arguments:
42   *   String target - name of an object, or RA DEC, eg "12.0 23.2" in decimal degrees (can also handle sexagesimal but let's ignore that...)
43   *   double radius - in units given by:
44   *   double units  - not sure what's valid. @see VizierUnits for enuemeration
45   *   String text - no idea.  Some kind of keyword?
46   *   String wavelength - not sure what's valid.  @see VizierWavelengths for enumeration
47   *
48   * @see http://cdsweb.u-strasbg.fr/cdsws/vizierAccess.gml
49   * @author M Hill
50   */
51  public class VizierQuerierPlugin extends DefaultPlugin  {
52     
53     String[] mirrorUrls = new String[] {
54        "http://cdsws.u-strasbg.fr/axis/services/VizieR",
55        "http://archive.ast.cam.ac.uk/axis/services/VizieR"
56     };
57     
58     
59     /*** default constructor */
60     public VizierQuerierPlugin() {
61        super();
62     }
63     
64     /* (non-Javadoc)
65      * @see org.astrogrid.datacenter.queriers.spi.QuerierSPI#doQuery(java.lang.Object, java.lang.Class)
66      */
67     public void askQuery(Account user, Query query, Querier querier) throws IOException {
68  
69        querier.setStatus(new QuerierQuerying(querier.getStatus()));
70  
71        //extract query to specific keys
72        KeywordMaker maker = new KeywordMaker(query);
73  
74        String text = (String) maker.getValue("TEXT");
75        String r = (String) maker.getRequiredValue(KeywordMaker.RADIUS_KEYWORD);
76        double radius = 0;
77        try {
78           radius = Double.parseDouble(r);
79        }
80        catch (NumberFormatException nfe) {
81           throw new IllegalArgumentException(KeywordMaker.RADIUS_KEYWORD+" has non-numeric value "+r);
82        }
83        
84        String u = (String) maker.getValue("UNIT");
85        VizierUnit unit = VizierUnit.getFor(RdbmsResourceReader.getUnitsOf("Vizier","Radius")); //default to what's in the resource file
86        if (u != null) {
87           unit = VizierUnit.getFor(u);
88        }
89        
90        String w = (String) maker.getValue("WAVELENGTH");
91        VizierWavelength wavelength = null;
92        if (w != null) { wavelength = VizierWavelength.getFor(w); }
93        
94        String target = (String) maker.getValue("TARGET");
95        String ra = (String) maker.getValue(KeywordMaker.RA_KEYWORD);
96        String dec = (String) maker.getValue(KeywordMaker.DEC_KEYWORD);
97        if (  ((ra == null) && (dec != null)) || ((ra != null) && (dec == null))  ) {
98           throw new IllegalArgumentException("RA is "+ra+" but DEC is "+dec);
99        }
100       if ( (target == null) && (ra == null) ) {
101          throw new IllegalArgumentException("TARGET or RA + DEC or CIRCLE must be specified in query");
102       }
103       if ( (target != null) && (ra != null) ) {
104          throw new IllegalArgumentException("Don't specify both TARGET and RA + DEC in query");
105       }
106       if (target == null) {
107          if (!dec.startsWith("-") && !dec.startsWith("+")) {
108             dec = "+"+dec; //add sign
109          }
110          
111          target = ra+" "+dec;
112       }
113 
114       //try each of the vizier services until one works
115       QueryResults results = null;
116       int site=0;
117       while ((results == null) && (site<mirrorUrls.length) && (!aborted)) {
118          try {
119             results = useSoap(mirrorUrls[site], querier, target, radius, unit, text, wavelength);
120          }
121          catch (IOException ioe) {
122             querier.getStatus().addDetail(ioe+" accessing "+mirrorUrls[site]);
123          }
124          site++;
125       }
126       if (aborted) return;
127       
128       if (results != null) {
129          results.send(query.getResultsDef(), user);
130       } else {
131          throw new IOException("No results from any of the Vizier services, details in the query status:\n"+querier.getStatus().asFullMessage());
132       }
133    }
134 
135    /* SOAP access - no good for large results */
136    protected QueryResults useSoap(String siteUrl, Querier querier, String target, double radius, VizierUnit unit, String text, VizierWavelength wavelength) throws IOException {
137       
138       try {
139 
140             VizieRService service = new VizieRServiceLocator();
141             VizieR vizier = service.getVizieR(new URL(siteUrl));
142             String response;
143             if (wavelength == null) {
144                querier.getStatus().addDetail("Calling vizier at "+siteUrl+" via SOAP, target='"+target+"', radius='"+radius+"', unit='"+unit+"' text='"+text+"'...");
145                response = vizier.cataloguesData(target, radius, unit.toString(), text);
146             }
147             else {
148                querier.getStatus().addDetail("Calling vizier at "+siteUrl+" via SOAP, target='"+target+"', radius='"+radius+"', unit='"+unit+"' text='"+text+"' wavelength='"+wavelength+"'...");
149                response = vizier.cataloguesData(target, radius, unit.toString(), text, wavelength.toString());
150             }
151             querier.getStatus().addDetail("Vizier Responded");
152             if (!aborted) {
153                if (response == null) {
154                   throw new DatacenterException("Vizier returned null");
155                }
156                return new VotableDomResults(querier, response);
157             }
158             return null;
159       }
160       catch (ServiceException e) {
161          throw new IOException("Could not connect to Vizier: "+e);
162       }
163       catch (SAXException e) {
164          throw new DatacenterException("XML Error in Vizier results: "+e,e);
165       }
166       catch (ParserConfigurationException e) {
167          throw new DatacenterException("Server not configured properly: "+e,e);
168       }
169       
170    }
171 
172    /*** Uses the http post provided by Axis along with the SOAP. This is better
173     for larger result sets than naively using SOAP, but seems to have troubles
174     * with timeouts as the socket timeout is not exposed here.  There are ways
175     around this see http://www.logicamente.com/sockets.html for example... */
176    protected QueryResults useHttp(String siteUrl, Querier querier, String target, double radius, VizierUnit unit, String text, VizierWavelength wavelength) throws IOException {
177       String url = siteUrl+"?method=cataloguesData&target="+target+"&radius="+radius+"&unit="+unit+"&text="+text;
178       if (wavelength != null) {
179          url = url + "&wavelength="+wavelength;
180       }
181       querier.getStatus().addDetail("Calling vizier via Url "+url+"...");
182 //    URLConnection connection = new URL(url).openConnection();
183       return new VotableInResults(querier, new URL(url).openStream());
184    }
185    
186    
187    /*** Returns just the number of matches rather than the list of matches. Since there's no way to do this yet
188     * directly with Vizier (I don't think?), we just do a normal query then count the rows */
189    public long getCount(Account user, Query query, Querier querier) throws IOException {
190       return getCountFromResults(user, query, querier);
191    }
192 
193    /*** Returns the formats that this plugin can provide.  Asks the results class; override in subclasse if nec */
194    public String[] getFormats() {
195       return VotableInResults.getFormats();
196    }
197    
198 }
199 
200 
201 /*
202  $Log: VizierQuerierPlugin.java,v $
203  Revision 1.13  2004/11/22 14:43:21  jdt
204  Restored Martin's changes from PAL_MCHJDT_705
205 
206  Revision 1.11  2004/11/12 13:49:12  mch
207  Fix where keyword maker might not have had keywords made
208 
209  Revision 1.10  2004/11/11 23:23:29  mch
210  Prepared framework for SSAP and SIAP
211 
212  Revision 1.9  2004/11/11 20:42:50  mch
213  Fixes to Vizier plugin, introduced SkyNode, started SssImagePlugin
214 
215  Revision 1.8  2004/11/08 02:59:13  mch
216  Fixes to connect to Vizier
217 
218  Revision 1.7  2004/11/07 14:10:14  mch
219  add pos sign to dec if not signed
220 
221  Revision 1.6  2004/11/03 05:14:33  mch
222  Bringing Vizier back online
223 
224  Revision 1.5  2004/11/03 00:31:17  mch
225  PAL_MCH Candidate 2 merge
226 
227  Revision 1.4  2004/11/03 00:17:56  mch
228  PAL_MCH Candidate 2 merge
229 
230  Revision 1.3.6.1  2004/10/27 00:43:39  mch
231  Started adding getCount, some resource fixes, some jsps
232 
233  Revision 1.3  2004/10/18 13:11:30  mch
234  Lumpy Merge
235 
236  Revision 1.2.4.1  2004/10/15 19:59:05  mch
237  Lots of changes during trip to CDS to improve int test pass rate
238 
239  Revision 1.2  2004/10/05 20:26:43  mch
240  Prepared for better resource metadata generators
241 
242  Revision 1.1  2004/10/05 19:19:18  mch
243  Merged CDS implementation into PAL
244 
245  Revision 1.5  2004/09/29 18:45:55  mch
246  Bringing Vizier into line with new(er) metadata stuff
247 
248  Revision 1.4  2004/08/14 14:35:42  acd
249  Fix the cone search in the Vizier Proxy.
250 
251  Revision 1.4  2004/08/13 16:50:00  acd
252  Added static final String METADATA.
253 
254  Revision 1.3  2004/08/12 17:31:00  acd
255  Added static final String CATALOGUE_NAME.
256 
257  Revision 1.2  2004/03/14 04:14:20  mch
258  Wrapped output target in TargetIndicator
259 
260  Revision 1.1  2004/03/13 23:40:59  mch
261  Changes to adapt to It05 refactor
262 
263  Revision 1.6  2003/12/09 16:25:08  nw
264  wrote plugin documentation
265 
266  Revision 1.5  2003/12/01 16:50:11  nw
267  first working tested version
268 
269  Revision 1.4  2003/11/28 19:12:16  nw
270  getting there..
271 
272  Revision 1.3  2003/11/25 11:14:51  nw
273  upgraded to new service interface
274 
275  Revision 1.2  2003/11/20 15:47:18  nw
276  improved testing
277 
278  Revision 1.1  2003/11/18 11:23:49  nw
279  mavenized cds delegate
280 
281  Revision 1.1  2003/11/18 11:10:05  nw
282  mavenized cds delegate
283  
284  */
285 
286 
287