1
2
3
4
5
6
7
8
9
10
11 package org.astrogrid.xdbserver.xql;
12
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.StringWriter;
16 import javax.xml.parsers.ParserConfigurationException;
17 import javax.xml.transform.Transformer;
18 import javax.xml.transform.TransformerConfigurationException;
19 import javax.xml.transform.TransformerException;
20 import javax.xml.transform.TransformerFactory;
21 import javax.xml.transform.dom.DOMSource;
22 import javax.xml.transform.stream.StreamResult;
23 import javax.xml.transform.stream.StreamSource;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.astrogrid.cfg.ConfigFactory;
27 import org.astrogrid.query.Query;
28 import org.astrogrid.query.QueryException;
29 import org.astrogrid.query.adql.Adql074Writer;
30 import org.astrogrid.xml.DomHelper;
31 import org.w3c.dom.Element;
32 import org.xml.sax.SAXException;
33
34 /***
35 * Creates XML from the query using transformation sheets
36 */
37 public class XqlMaker {
38
39 private static final Log log = LogFactory.getLog(XqlMaker.class);
40
41
42 /***
43 * Constructs an XQL statement for the given ADQL
44 */
45 public String fromAdql(Query query) throws QueryException, IOException {
46
47 Element adql = null;
48
49 try {
50 adql = DomHelper.newDocument(Adql074Writer.makeAdql(query)).getDocumentElement();
51 }
52 catch (SAXException e) {
53 throw new RuntimeException("Query2Adql074 procuced invalid XML from query "+query,e);
54 }
55
56
57 String namespaceURI = adql.getNamespaceURI();
58 if (namespaceURI == null) {
59
60 namespaceURI = adql.getAttribute("xmlns");
61 }
62 if (namespaceURI == null) {
63 DomHelper.PrettyElementToStream(adql,System.out);
64 throw new IllegalArgumentException("Query body has no namespace - cannot determine language");
65 }
66
67 String xql = useXslt(adql, namespaceURI);
68
69 return xql;
70
71 }
72
73
74 /*** Uses Xslt to do the translations */
75 public String useXslt(Element queryBody, String namespaceURI) throws QueryException {
76
77 String xsltDoc = null;
78
79
80
81
82 if ((namespaceURI==null) || (namespaceURI.length()==0)) {
83 throw new QueryException("No namespace specified in query document, so don't know what it is");
84 }
85 else if (namespaceURI.equals("http://tempuri.org/adql")) { //assume v0.5
86 xsltDoc = "adql05-2-sql.xsl";
87 }
88 else if (namespaceURI.equals("http://adql.ivoa.net/v0.73")) {
89
90
91 xsltDoc = "adql073-2-xql_fits.xsl";
92 }
93 else if (namespaceURI.equals("http://www.ivoa.net/xml/ADQL/v0.7.4")) {
94 xsltDoc = "adql074-2-xql_fits.xsl";
95 }
96
97
98
99 else if (namespaceURI.equals("http://astrogrid.org/sadql/v1.1")) {
100 xsltDoc = "sadql1.1-2-sql.xsl";
101 }
102
103
104 String key = "datacenter.sqlmaker.xslt."+namespaceURI.replaceAll(":","_");
105 xsltDoc = ConfigFactory.getCommonConfig().getString(key, xsltDoc);
106
107 if (xsltDoc == null) {
108 throw new RuntimeException("No XSLT sheet given for ADQL (namespace '"+namespaceURI+"'); set configuration key '" + key+"'");
109 }
110
111 Transformer transformer = null;
112 try {
113
114
115 ClassLoader loader = this.getClass().getClassLoader();
116 InputStream xsltIn = loader.getResourceAsStream(xsltDoc);
117
118 if (xsltIn == null) {
119 throw new QueryException("Could not find/create ADQL->XQL transformer doc "+xsltDoc);
120 }
121
122 log.debug("Transforming ADQL ["+namespaceURI+"] using Xslt doc at './xslt/"+xsltDoc+"'");
123 TransformerFactory tFactory = TransformerFactory.newInstance();
124 transformer = tFactory.newTransformer(new StreamSource(xsltIn));
125 try {
126 tFactory.setAttribute("UseNamespaces", Boolean.FALSE);
127 }
128 catch (IllegalArgumentException iae) {
129
130
131 }
132
133 StringWriter sw = new StringWriter();
134 transformer.transform(new DOMSource(queryBody), new StreamResult(sw));
135 String xql = sw.toString();
136
137
138 xql = xql.replaceAll("\n","");
139 xql = xql.replaceAll("\r","");
140 while (xql.indexOf(" ")>-1) { xql = xql.replaceAll(" ", " "); }
141
142
143 if (xql.startsWith("<?")) {
144 xql = xql.substring(xql.indexOf("?>")+2);
145 }
146
147 xql = xql.replaceAll(">", ">").replaceAll("<", "<");
148
149 log.debug("Used '"+xsltDoc+"' to translate ADQL ("+namespaceURI+") to '"+xql+"'");
150
151 return xql;
152 }
153 catch (TransformerConfigurationException tce) {
154 throw new QueryException(tce+" (using xslt sheet "+xsltDoc+")",tce);
155 }
156 catch (TransformerException te) {
157 throw new QueryException(te+" translating ADQL->SQL using "+xsltDoc,te);
158 }
159
160 }
161
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
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