1
2
3
4
5
6
7 package org.astrogrid.tableserver.out;
8
9 import java.io.IOException;
10 import java.io.OutputStream;
11 import java.util.Vector;
12 import org.astrogrid.io.mime.MimeNames;
13 import org.astrogrid.tableserver.metadata.ColumnInfo;
14 import uk.ac.starlink.table.AbstractStarTable;
15 import uk.ac.starlink.table.RowSequence;
16 import uk.ac.starlink.table.StarTableWriter;
17
18 /***
19 * Adaptor to the STIL (Starlink Library) StarTableWriter,
20 * which can then be used to create fits files, votables, etc.
21 * However it's a non streaming build (the whole table is built) so use with care
22 * <p>
23 * An alternative, if there is a suitable StarTable representation of the data
24 * source, is to just create the appropriate StarTableWriter around the appropriate StarTable
25 * (essentially a table reader) and write it out.
26 *
27 * @author M Hill
28 */
29
30 public class StilStarTableWriter extends AbstractStarTable implements TableWriter {
31
32 StarTableWriter starWriter = null;
33
34 OutputStream out = null;
35
36 ColumnInfo[] cols = null;
37 Vector rows = new Vector();
38
39 /***
40 * Constructor for a table with the given anme
41 */
42 public StilStarTableWriter(StarTableWriter writer, OutputStream target) throws IOException {
43 starWriter = writer;
44 this.out = target;
45 }
46
47 /*** Opens writer = does nothing */
48 public void open() {
49 }
50
51 /*** Closes writer - does nothing
52 */
53 public void close() throws IOException {
54 }
55
56 /*** try and return mime type from starWriters' format name */
57 public String getMimeType() {
58 return MimeNames.getMimeType(starWriter.getFormatName());
59 }
60
61 /*** Starts table - stores column info for write */
62 public void startTable(ColumnInfo[] newCols) throws IOException {
63 cols = newCols;
64 }
65
66
67 /*** Writes the given array of values out */
68 public void writeRow(Object[] colValues) throws IOException {
69 rows.add(colValues);
70 }
71
72 public void endTable() throws IOException {
73 throw new UnsupportedOperationException();
74
75 }
76
77
78 /*** Aborting does nothing as nothing happens until endtable anyway */
79 public void abort() {
80 }
81
82 /***
83 * StarTable implementation, returns the number of rows built
84 */
85 public long getRowCount() {
86 return rows.size();
87 }
88
89 /***
90 * StarTable implementation, returns the number of columns stored
91 */
92 public int getColumnCount() {
93 return cols.length;
94 }
95
96 /***
97 * StarTable implementation, returns the columinfo suitable for startable
98 */
99 public uk.ac.starlink.table.ColumnInfo getColumnInfo(int icol) {
100 uk.ac.starlink.table.ColumnInfo starColumn = new uk.ac.starlink.table.ColumnInfo(cols[icol].getName());
101 starColumn.setUnitString(cols[icol].getUnits().toString());
102 starColumn.setUCD(cols[icol].getUcd("1"));
103 starColumn.setContentClass(cols[icol].getJavaType());
104 return starColumn;
105 }
106
107 /***
108 * StarTable implementation, returns access to the rows
109 */
110 public RowSequence getRowSequence() throws IOException {
111 return new RowAdaptor();
112 }
113
114 private class RowAdaptor implements RowSequence {
115
116 int rowCursor = -1;
117 /***
118 * Indicates whether this table contains any more rows after the current
119 * one.
120 */
121 public boolean hasNext() {
122 return (rowCursor<rows.size());
123 }
124
125 /***
126 * Returns the contents of the current table row, as an array
127 * with the same number of elements as there are columns in this
128 * table.
129 * An unchecked exception will be thrown if there is no current
130 * row (<tt>next</tt> has not yet been called).
131 *
132 * @return an array of the objects in each cell in row <tt>irow</tt>
133 * @throws IOException if there is an error reading the data
134 */
135 public Object[] getRow() throws IOException {
136 if (rowCursor == -1) {
137 throw new IllegalStateException("Next not yet called");
138 }
139 return (Object[]) rows.get(rowCursor);
140 }
141
142 /***
143 * Indicates that this sequence will not be required any more.
144 * This should release resources associated with this object.
145 * The effect of calling any of the other methods following a
146 * <code>close</code> is undefined.
147 */
148 public void close() throws IOException {
149 cols = null;
150 rows = null;
151 }
152
153 /***
154 * Advances the current row to the next one.
155 * Since the initial position of a RowSequence is before the first row,
156 * this method must be called before current row data
157 * can be accessed using the
158 * {@link #getCell(int)} or {@link #getRow()} methods.
159 * An unchecked exception such as <tt>NoSuchElementException</tt>
160 * will be thrown if {@link #hasNext} returns <tt>false</tt>.
161 *
162 * @throws IOException if there is some error in the positioning
163 */
164 public void next() throws IOException {
165 rowCursor++;
166 }
167
168 /***
169 * Returns the contents of a cell in the current row.
170 * The class of the returned object should be the same as,
171 * or a subclass of, the class returned by
172 * <tt>getColumnInfo(icol).getContentClass()</tt>.
173 * An unchecked exception will be thrown if there is no current
174 * row (<tt>next</tt> has not yet been called).
175 *
176 * @return the contents of cell <tt>icol</tt> in the current row
177 * @throws IOException if there is an error reading the data
178 * @throws IllegalStateException if there is no current row (before the
179 * start of the table)
180 */
181 public Object getCell(int icol) throws IOException {
182 return getRow()[icol];
183 }
184
185 }
186
187 }
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250