1
2
3
4
5
6
7 package org.astrogrid.tableserver.jdbc;
8
9 import java.io.IOException;
10 import java.io.StringWriter;
11 import java.io.Writer;
12 import java.sql.Connection;
13 import java.sql.DatabaseMetaData;
14 import java.sql.ResultSet;
15 import java.sql.SQLException;
16 import java.sql.Types;
17 import javax.servlet.http.HttpServletRequest;
18 import javax.servlet.http.HttpServletResponse;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.astrogrid.dataservice.queriers.DatabaseAccessException;
22 import org.astrogrid.io.xml.XmlAsciiWriter;
23 import org.astrogrid.io.xml.XmlPrinter;
24 import org.astrogrid.webapp.DefaultServlet;
25
26 import org.astrogrid.dataservice.metadata.StdDataTypes;
27 import org.astrogrid.tableserver.test.SampleStarsPlugin;
28 import org.astrogrid.cfg.ConfigFactory;
29
30
31 /***
32 * Generates the table metadoc that describes a tabular dataset from the metadata
33 * provided by the JDBC connection. Comes in handy servlet form for easy web use.
34 */
35
36 public class RdbmsTableMetaDocGenerator extends DefaultServlet {
37
38 protected static Log log = LogFactory.getLog(RdbmsTableMetaDocGenerator.class);
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 /*** Convenience routine for finding the value of a column in a result set row,
55 * but ignoring
56 * missing columns
57 */
58 protected String getColumnValue(ResultSet table, String column) {
59 try {
60 String s = table.getString(column);
61 if (s==null) {
62 return "";
63 }
64 else {
65 return s;
66 }
67 }
68 catch (SQLException e) {
69 return "(Unknown)";
70 }
71 }
72
73 /***
74 * Returns the votable datatype for the given column.
75 * @todo check these - these are made up/guessed
76 */
77 public static String getType(int sqlType, int typeSize) {
78
79 switch (sqlType) {
80 case Types.ARRAY : log.error("Don't know how to cope with Arrays, storing as string", new RuntimeException()); return StdDataTypes.STRING;
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 case Types.BIGINT: return StdDataTypes.LONG;
100 case Types.BOOLEAN: return StdDataTypes.BOOLEAN;
101 case Types.BIT: return StdDataTypes.SHORT;
102 case Types.CHAR:
103 if (typeSize == 1) {
104 return StdDataTypes.CHAR;
105 }
106 else {
107 return StdDataTypes.STRING;
108 }
109 case Types.DATE: return StdDataTypes.DATE;
110 case Types.DECIMAL: return StdDataTypes.DOUBLE;
111 case Types.DOUBLE: return StdDataTypes.DOUBLE;
112 case Types.FLOAT: return StdDataTypes.FLOAT;
113 case Types.INTEGER: return StdDataTypes.INT;
114
115 case Types.REAL: return StdDataTypes.DOUBLE;
116 case Types.SMALLINT: return StdDataTypes.INT;
117 case Types.TINYINT: return StdDataTypes.SHORT;
118 case Types.TIMESTAMP:return StdDataTypes.DATE;
119 case Types.VARCHAR: return StdDataTypes.STRING;
120 default: {
121 log.error("Don't know what SQL type "+sqlType+" should be, storing as string", new RuntimeException());
122 return StdDataTypes.STRING;
123 }
124 }
125 }
126
127 /*** Returns the metadata as a string */
128 public String getMetaDoc() throws IOException {
129 StringWriter sw = new StringWriter();
130 writeTableMetaDoc(sw);
131 return sw.toString();
132 }
133
134
135 /***
136 * Writes the metadata to the given stream. Writes just one catalog for now */
137 public void writeTableMetaDoc(Writer out) throws IOException {
138
139
140
141 String plugin = ConfigFactory.getCommonConfig().getString(
142 "datacenter.querier.plugin");
143 if (plugin.equals("org.astrogrid.tableserver.test.SampleStarsPlugin")) {
144
145 SampleStarsPlugin.initialise();
146 }
147
148
149
150
151 Connection connection = null;
152 try {
153 connection = JdbcPlugin.getJdbcConnection();
154
155 DatabaseMetaData metadata = connection.getMetaData();
156
157 XmlAsciiWriter xw = new XmlAsciiWriter(out, false);
158
159
160
161 XmlPrinter rootTag = xw.newTag("DatasetDescription", new String[] {"xmlns='urn:astrogrid:schema:TableMetaDoc:v1'"});
162 XmlPrinter catTag = rootTag.newTag("Catalog");
163
164 XmlPrinter catNameTag = catTag.newTag("Name");
165 catNameTag.close();
166 XmlPrinter catDescTag = catTag.newTag("Description");
167 catDescTag.close();
168
169
170 ResultSet tables = metadata.getTables(null, null, "%", null);
171
172 while (tables.next()) {
173
174
175
176 if (
177 (!getColumnValue(tables, "TABLE_NAME").startsWith("sys")) &&
178 (!getColumnValue(tables, "TABLE_NAME").startsWith("SYSTEM"))
179 ) {
180 String tableName = getColumnValue(tables, "TABLE_NAME");
181 XmlPrinter tableTag = catTag.newTag("Table", new String[] { "ID='"+tableName+"'"} );
182 tableTag.writeTag("Name", tableName );
183 tableTag.writeTag("Description", getColumnValue(tables, "REMARKS")+" ");
184
185
186 ResultSet columns = metadata.getColumns(null, null, tables.getString("TABLE_NAME"), "%");
187
188 while (columns.next()) {
189
190 int sqlType = Integer.parseInt(getColumnValue(columns, "DATA_TYPE"));
191
192
193
194
195
196 int typeSize;
197 try {
198 typeSize = Integer.parseInt(getColumnValue(columns, "COLUMN_SIZE"));
199 }
200 catch (java.lang.NumberFormatException e) {
201 typeSize = 1;
202 }
203 String colName = getColumnValue(columns, "COLUMN_NAME");
204 XmlPrinter colTag = tableTag.newTag(
205 "Column",
206 new String[] { "ID='"+tableName+"."+colName+"'",
207 "indexed='false'" }
208 );
209 colTag.writeTag("Name", colName);
210 colTag.writeTag("Datatype", getType(sqlType, typeSize));
211 colTag.writeTag("Description", getColumnValue(columns, "REMARKS")+" ");
212
213 colTag.writeTag("Units", " ");
214 colTag.writeTag("DimEq", " ");
215 colTag.writeTag("Scale", " ");
216
217
218
219 colTag.writeTag("UCD", new String[] {"version='1'"} ," ");
220 colTag.writeTag("UCD", new String[] {"version='1+'"} ," ");
221
222 colTag.writeTag("ErrorColumn", " ");
223
224 if (colName.toLowerCase().equals("ra")) {
225 colTag.writeTag("SkyPolarCoord", "RA");
226 }
227 if (colName.toLowerCase().equals("dec")) {
228 colTag.writeTag("SkyPolarCoord", "DEC");
229 }
230
231 colTag.close();
232 }
233
234 tableTag.close();
235 }
236 }
237 catTag.close();
238 rootTag.close();
239 xw.close();
240
241 connection.close();
242 }
243 catch (SQLException e) {
244 throw new DatabaseAccessException("Could not get metadata: "+e,e);
245 }
246
247
248
249
250
251
252 }
253
254
255 /*** Servlet implementation so we can run it nicely from a web interface */
256 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
257
258 try {
259 response.setContentType("text/xml");
260
261 writeTableMetaDoc(response.getWriter());
262 }
263 catch (Throwable th) {
264 doError(response, "Generating Resource Metadata",th);
265 }
266 }
267
268 /*** for testing/debugging etc */
269 public static void main(String[] args) {
270
271
272 }
273
274 }
275
276