1 /*
2 * $Id: VoTableWriter.java,v 1.9 2006/10/17 10:11:41 clq2 Exp $
3 *
4 * (C) Copyright Astrogrid...
5 */
6
7 package org.astrogrid.tableserver.out;
8 import java.io.BufferedWriter;
9 import java.io.IOException;
10 import java.io.PrintWriter;
11 import java.io.Writer;
12 import java.security.Principal;
13 import java.util.Date;
14 import org.apache.commons.logging.Log;
15 import org.astrogrid.dataservice.metadata.StdDataTypes;
16 import org.astrogrid.dataservice.metadata.VoTypes;
17 import org.astrogrid.io.mime.MimeTypes;
18 import org.astrogrid.slinger.targets.TargetIdentifier;
19 import org.astrogrid.tableserver.metadata.ColumnInfo;
20 import org.astrogrid.ucd.UcdVersions;
21 import org.astrogrid.ucd.UcdException;
22
23 /***
24 * For writing out tables in votable. As far as I'm aware dates are not handled
25 * by VOTables (by Jan 2005). Since I'm stroppely ignoring VOTable development as
26 * irrelevent (ie I'm not going to try and push for standard date support, they can
27 * get around to it whenever), dates here are written as the 'C standard' number of seconds since
28 * 1970 (negative numbers before 1970), with type 'float' so we can provide milliseconds
29 * etc. NB we need to handle dates from several thousand BC.
30 *
31 * @author M Hill
32 */
33
34 public class VoTableWriter implements TableWriter {
35
36
37 protected static final Log log = org.apache.commons.logging.LogFactory.getLog(VoTableWriter.class);
38
39 protected PrintWriter printOut = null;
40
41 protected ColumnInfo[] cols = null;
42
43 /***
44 * Construct this wrapping the given stream.
45 */
46 public VoTableWriter(TargetIdentifier target, String title, Principal user) throws IOException {
47
48 target.setMimeType(MimeTypes.VOTABLE);
49
50 printOut = new PrintWriter(new BufferedWriter(target.openWriter()));
51 }
52
53 public void open() {
54 printOut.println("<?xml version='1.0' encoding='UTF-8'?>");
55 printOut.println("<VOTABLE "
56 +"xmlns='http://www.ivoa.net/xml/VOTable/v1.1' "
57 +"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
58 +"xsi:schemaLocation='http://www.ivoa.net/xml/VOTable/v1.1 http://software.astrogrid.org/schema/vo-formats/VOTable/v1.1/VOTable.xsd' "
59 +"version='1.1'"
60 +">");
61
62 /* don't know where to find this info - in the netadata I expect
63 <DEFINITIONS>
64 <COOSYS ID="myJ2000" system="eq_FK5" equinox="2000." epoch="2000."/>
65 </DEFINITIONS>
66 */
67
68 printOut.println("<RESOURCE>");
69 /* don't know where to find this info - in the netadata I expect
70 <PARAM ID="RA" datatype="E" value="200.0"/>
71 <PARAM ID="DE" datatype="E" value="40.0"/>
72 <PARAM ID="SR" datatype="E" value="30.0"/>
73 <PARAM ID="PositionalError" datatype="E" value="0.1"/>
74 <PARAM ID="Credit" datatype="A" arraysize="*" value="Charles Messier, Richard Gelderman"/>
75 */
76
77
78 }
79
80
81 /*** Produces text/html */
82 public String getMimeType() {
83 return MimeTypes.VOTABLE;
84 }
85
86
87 /*** Start body - writes out header and preps col array */
88 public void startTable(ColumnInfo[] colinfo) throws IOException {
89
90 String ucdVersion = UcdVersions.getUcdVersion();
91
92 this.cols = colinfo;
93
94 printOut.println("<TABLE>");
95
96 for (int i = 0; i < cols.length; i++) {
97 if (cols[i] != null) { // null columns if it's not been found in the metadoc
98
99 printOut.print("<FIELD name='"+cols[i].getName()+"' ");
100 if (cols[i].getId() != null) printOut.print("ID='"+cols[i].getId()+"' ");
101 if (cols[i].getUcd(ucdVersion) != null) printOut.print(" ucd='"+cols[i].getUcd(ucdVersion)+"' ");
102
103 //Create the votable type attributes from the metadoc type.
104 //Convert using java class as the medium
105 if (cols[i].getPublicType() != null) {
106 Class colType = StdDataTypes.getJavaType(cols[i].getPublicType());
107 printOut.print(VoTypes.getVoTableTypeAttributes(colType));
108 }
109 /*
110 // KEA FUTURE: I added this, but not sure if it should
111 // work or not, needs further investigation.
112 // Try java type if no public type
113 else if (cols[i].getJavaType() != null) {
114 printOut.print(VoTypes.getVoTableTypeAttributes(
115 cols[i].getJavaType()));
116 }
117 */
118 else {
119 // Use String type as default, since any real data type
120 // will be parsable as a string. THis is not ideal;
121 // hopefully we can fix the problem of not knowing the
122 // type in future.
123 printOut.print(VoTypes.getVoTableTypeAttributes(String.class));
124 }
125
126 //units
127 if (cols[i].getJavaType() == Date.class) {
128 printOut.print(" unit='s' ");
129 }
130 else {
131 if ((cols[i].getUnits() != null) && (cols[i].getUnits().toString().trim().length()>0)) {
132 printOut.print(" unit='"+cols[i].getUnits()+"' ");
133 }
134 }
135 printOut.println("/>");
136 }
137 }
138
139 printOut.flush(); //so something comes back to the browser quickly
140
141 //start body table
142 printOut.println("<DATA>");
143 printOut.println("<TABLEDATA>");
144
145 }
146
147 /*** Writes the given array of values out */
148 public void writeRow(Object[] colValues) throws IOException {
149
150 printOut.print("<TR>");
151 for (int i=0;i<colValues.length;i++) {
152 if (cols[i] != null) { //skip columns with no metadata
153 if (colValues[i] instanceof Date) {
154 printOut.print("<TD>"+ (float) (((Date) colValues[i]).getTime()/1000) +"</TD>");
155 }
156 else {
157 if ( (colValues[i] == null) || (colValues[i].equals("null")) ){
158 //From VOTable spec: "In the TABLEDATA data representation,
159 //the default representation of a ``null'' value is an
160 //empty column (i.e. <TD></TD>)";
161 printOut.print("<TD></TD>");
162 }
163 else {
164 printOut.print("<TD>"+colValues[i]+"</TD>");
165 }
166 }
167 }
168 }
169 printOut.println("</TR>");
170
171 }
172
173 public void endTable() {
174 //close row body
175 printOut.println("</TABLEDATA>");
176 printOut.println("</DATA>");
177
178 //close document
179 printOut.println("</TABLE>");
180 }
181
182 /*** Closes writer - writes out the closing tags and closes wrapped stream
183 */
184 public void close() {
185
186 printOut.println("</RESOURCE>");
187
188 printOut.println("</VOTABLE>");
189
190 printOut.close();
191 }
192
193 /*** Abort writes out a line to show the table is incomplete */
194 public void abort() {
195 printOut.println("<tr><td> ------------------ Writing Aborted -----------------</td></tr> ");
196 close();
197 }
198
199 /*** Convenience method to get direct access to the output stream, so that we can pipe votables direct */
200 public Writer getOut() {
201 return printOut;
202 }
203
204 }
205
206 /*
207 $Log: VoTableWriter.java,v $
208 Revision 1.9 2006/10/17 10:11:41 clq2
209 PAL_KEA_1869
210
211 Revision 1.8.2.1 2006/10/12 16:40:15 kea
212 Tweaks while fixing registration issues (see bugzilla ticket 1920)
213
214 Revision 1.8 2006/09/26 15:34:43 clq2
215 SLI_KEA_1794 for slinger and PAL_KEA_1974 for pal and xml, deleted slinger jar from repo, merged with pal
216
217 Revision 1.7.10.2 2006/09/19 12:19:47 kea
218 Fixing TabularDB registrations to use system-default UCD version;
219 moved ucd version management stuff to org.astrogrid.ucd package.
220
221 Revision 1.7.10.1 2006/09/14 14:53:03 kea
222 Updating.
223
224 Revision 1.7 2006/06/15 16:50:10 clq2
225 PAL_KEA_1612
226
227 Revision 1.6.26.2 2006/06/15 14:08:04 kea
228 Nearly ready to branch.
229
230 Revision 1.6.26.1 2006/06/13 21:05:17 kea
231 Getting tests working fully after Jeff's new ADQLbeans jar.
232
233 Revision 1.6 2005/11/21 12:54:18 clq2
234 DSA_KEA_1451
235
236 Revision 1.5.38.1 2005/11/15 15:38:46 kea
237 Layout change only.
238
239 Revision 1.5 2005/05/27 16:21:02 clq2
240 mchv_1
241
242 Revision 1.4.10.3 2005/05/13 16:56:32 mch
243 'some changes'
244
245 Revision 1.4.10.2 2005/04/28 17:14:49 mch
246 fix to not add 'unit' if unit is empty
247
248 Revision 1.4.10.1 2005/04/21 17:20:51 mch
249 Fixes to output types
250
251 Revision 1.4 2005/03/30 21:51:25 mch
252 Fix to return Votable fits list for url list
253
254 Revision 1.3 2005/03/30 18:54:03 mch
255 fixes to results format
256
257 Revision 1.2 2005/03/30 15:52:15 mch
258 debug etc for bad sql types
259
260 Revision 1.1 2005/03/21 18:45:55 mch
261 Naughty big lump of changes
262
263 Revision 1.4 2005/03/10 15:13:48 mch
264 Seperating out fits, table and xdb servers
265
266 Revision 1.3 2005/03/10 13:49:52 mch
267 Updating metadata
268
269 Revision 1.2 2005/03/01 15:58:33 mch
270 Changed to use starlinks tamfits library
271
272 Revision 1.1.1.1 2005/02/17 18:37:34 mch
273 Initial checkin
274
275 Revision 1.1.1.1 2005/02/16 17:11:24 mch
276 Initial checkin
277
278 Revision 1.1.2.10 2005/01/24 12:14:28 mch
279 Fixes to VizieR proxy and resource stuff
280
281 Revision 1.1.2.9 2005/01/13 18:57:31 mch
282 Fixes to metadata mostly
283
284 Revision 1.1.2.8 2004/12/13 21:53:14 mch
285 Made the java types the intermediate types, added types to Xsv and html output
286
287 Revision 1.1.2.7 2004/12/08 18:36:40 mch
288 Added Vizier, rationalised SqlWriters etc, separated out TableResults from QueryResults
289
290 Revision 1.1.2.6 2004/12/07 21:21:09 mch
291 Fixes after a days integration testing
292
293 Revision 1.1.2.5 2004/12/07 00:49:42 mch
294 minor changes to put rows on one line (compact)
295
296 Revision 1.1.2.4 2004/12/06 02:50:30 mch
297 a few bug fixes
298
299 Revision 1.1.2.3 2004/12/05 19:33:16 mch
300 changed skynode to 'raw' soap (from axis) and bug fixes
301
302 Revision 1.1.2.2 2004/11/30 02:32:18 mch
303 fix to 0-base of writerows
304
305 Revision 1.1.2.1 2004/11/30 01:26:42 mch
306 added tablewriters
307
308
309
310 */
311
312
313