package dalclient; import edu.jhu.pha.ivoa.*; import java.io.*; import java.net.*; import java.util.*; /** * SIAP query. Provides methods to build up and execute a query against * a pre-established connection. */ public class SiapQuery extends DALQuery { SiapQuery(SiapConnection conn) { super(conn); } /* Execute query and write to the given output stream in CSV format. * For images the column labels are the SIA data model attribute names * rather than UCDs. */ public void executeCSV(PrintStream out) throws Exception { QueryResponse resultSet = execute(); QueryRecord qr = resultSet.getRecord(0); LinkedHashMap m = qr.getMap(); Set s = m.entrySet(); Iterator i; int arg = 0; // Output the table header in CSV. for (arg=0, i=s.iterator(); i.hasNext(); arg++) { Map.Entry me = (Map.Entry) i.next(); String colname = (String) me.getKey(); if (arg > 0) System.out.print(","); out.print(colname); } out.println(""); // Output the table data. for (int j=0; j < resultSet.getRecordCount(); j++) { qr = resultSet.getRecord(j); m = qr.getMap(); s = m.entrySet(); for (arg=0, i=s.iterator(); i.hasNext(); arg++) { Map.Entry me = (Map.Entry) i.next(); String sdata = (String) me.getValue(); if (arg > 0) out.print(","); out.print(sdata.replace(',', ' ')); } out.println(""); } } /* * Execute query and process the resultant VOTable into a SIAP query * response class. To do this we have to extact the elements of the * SIAP data model into attributes in SiapQuery. * * TODO: Add support for querying multiple services and merging the * results. */ public QueryResponse execute() throws Exception { ArrayList resultSet = new ArrayList(); VOTWrap.VOTable vot = this.executeVOTable(); // The following ought to be a bit more careful about checking for // a valid query response, dealing with multiple resources, etc. VOTWrap.Resource r = vot.getResource(0); VOTWrap.Table table = r.getTable(0); // Read the table header; form array of field to keyword mappings. // Fields with UCDs not defined by SIA are passed through as-is. // SIA V1.0 does not use UTYPE so we do nothing with UTYPE here. ArrayList fieldKeys = new ArrayList(); for (int i=0; i < table.getFieldCount(); i++) { VOTWrap.Field field = table.getField(i); // Try to map the field to a SIA data model attribute name. String ucd = field.getUCD(); String key = SIAV10map.mapUCD(ucd); // Make sure we have some sort of key for the field. if (key == null) key = ucd; if (key == null) key = field.getName(); if (key == null) key = new Integer(i).toString(); fieldKeys.add(key); } // Read the table data; produce a "fields" hashMap for each row. int TRCount = table.getTableData().getTRCount(); for (int j=0; j < TRCount; j++) { LinkedHashMap fields = new LinkedHashMap(); VOTWrap.TR row = table.getTableData().getTR(j); for (int i=0; i < table.getFieldCount(); i++) fields.put(fieldKeys.get(i), row.getTD(i).getPCDATA()); resultSet.add(fields); } QueryResponse qr = new QueryResponse(resultSet); return (qr); } /* Map SIA V1.0 UCDs to SIA interface attributes. This is where * we map the SIAP-defined UCDs in the rows of the VOTable to the * protocol-independent SIA dataset descriptor data model. This * isolates the client code from changes to details of the underlying * protocol, including versioning (except for changes to the data model * itself). */ private static class SIAV10map { static final LinkedHashMap m = new LinkedHashMap(32); static { // SIA dataset attribute // SIA V1.0 UCD in VOTable enter("Title", "VOX:Image_Title"); enter("RA", "POS_EQ_RA_MAIN"); enter("DEC", "POS_EQ_DEC_MAIN"); enter("Instrument", "INST_ID"); enter("MJDateObs", "VOX:Image_MJDateObs"); enter("Naxes", "VOX:Image_Naxes"); enter("Naxis", "VOX:Image_Naxis"); enter("Scale", "VOX:Image_Scale"); enter("Format", "VOX:Image_Format"); enter("CoordRefFrame", "VOX:STC_CoordRefFrame"); enter("CoordEquinox", "VOX:STC_CoordEquinox"); enter("CoordProjection", "VOX:STC_CoordProjection"); enter("CoordRefPixel", "VOX:STC_CoordRefPixel"); enter("CoordRefValue", "VOX:STC_CoordRefValue"); enter("CDMatrix", "VOX:STC_CDMatrix"); enter("BandPass_ID", "VOX:BandPass_ID"); enter("BandPass_Unit", "VOX:BandPass_Unit"); enter("BandPass_RefValue", "VOX:BandPass_RefValue"); enter("BandPass_HiLimit", "VOX:BandPass_HiLimit"); enter("BandPass_LoLimit", "VOX:BandPass_LoLimit"); enter("PixFlags", "VOX:Image_PixFlags"); enter("AccessReference", "VOX:Image_AccessReference"); enter("AccessRefTTL", "VOX:Image_AccessRefTTL"); enter("Filesize", "VOX:Image_FileSize"); } // Enter an attribute-UCD pair into the hashmap (makes UCD the key). static void enter(String attribute, String ucd) { m.put(ucd, attribute); } // Map a SIA V1.0 UCD to the corresponding data model attribute name. static String mapUCD(String ucd) { return ((String) m.get(ucd)); } // Get the hashmap. static LinkedHashMap getMap() { return (m); } } }