1
2
3
4
5
6
7
8
9
10
11 package org.astrogrid.dataservice.impl.cds;
12
13 import org.astrogrid.query.condition.*;
14
15 import java.io.IOException;
16 import java.net.URLEncoder;
17 import org.astrogrid.query.Query;
18 import org.astrogrid.query.QueryTraverser;
19 import org.astrogrid.query.returns.ReturnSpec;
20 import org.astrogrid.query.returns.ReturnTable;
21 import org.astrogrid.query.sql.SqlParser;
22 import org.astrogrid.slinger.mime.MimeNames;
23
24 /*** Makes an ASU URL 'twig' that can be attached to a URL stem to query
25 * an ASU-compatible server. Actually I think there is only one ASU-compatible
26 * server, ie VizieR
27 * <p>
28 * @see http://vizier.u-strasbg.fr/doc/asu.html
29 * <p>
30 * @author M Hill
31 */
32 public class AsuTwigMaker extends QueryTraverser {
33
34 StringBuffer asuTwig = new StringBuffer();
35
36 /*** Case is important */
37 public void visitColumnReference(ColumnReference colRef) throws IOException {
38
39 asuTwig.append(colRef.getColName());
40 }
41
42 public void visitAngle(LiteralAngle angle) throws IOException {
43 asuTwig.append(angle.getAngle().asDegrees());
44 }
45
46 public void visitLimit(long limit) throws IOException {
47 if (limit>0) {
48 asuTwig.append("-out.max="+limit);
49 }
50 }
51
52 public void visitNumber(LiteralNumber number) throws IOException {
53 asuTwig.append(number.getValue());
54 }
55
56 public void visitString(LiteralString string) throws IOException {
57 asuTwig.append(string.getValue());
58 }
59
60 public void visitDate(LiteralDate date) throws IOException {
61 asuTwig.append(URLEncoder.encode(date.getDate().toString()));
62 }
63
64 public void visitRawSearchField(RawSearchField field) throws IOException {
65 asuTwig.append(field.getField());
66 }
67
68
69 public void visitCircle(CircleCondition circle) {
70 asuTwig.append("&-c.eq="+circle.getEquinox()+
71 "&-c.ra="+circle.getRa().asDegrees()+
72 "&-c.dec="+circle.getDec().asDegrees()+
73 "&-c.rd="+circle.getRadius().asDegrees());
74 }
75
76 public void visitReturnSpec(ReturnSpec spec) {
77 if (!spec.getFormat().equals(ReturnSpec.DEFAULT)) {
78 String format = spec.getFormat();
79
80 format = MimeNames.humanFriendly(format).toLowerCase();
81 asuTwig.append("&-mime="+format);
82 }
83
84 String outfields = "";
85 if (spec instanceof ReturnTable) {
86 Expression[] cols = ((ReturnTable) spec).getColDefs();
87 if (cols != null) {
88 for (int i = 0; i < cols.length; i++) {
89 if (cols[i] instanceof ColumnReference) {
90 outfields=outfields+ ((ColumnReference) cols[i]).getColName()+",";
91 }
92 else if (cols[i] instanceof RawSearchField) {
93 outfields=outfields+ ((RawSearchField) cols[i]).getField()+",";
94 }
95 else {
96 throw new IllegalArgumentException("Specify only column/field names in the Return Table Specification (eg SELECT) for ASU queries");
97 }
98 }
99 }
100 }
101 if (outfields.length()>0) {
102 asuTwig.append("&-out="+outfields.substring(0,outfields.length()-1));
103 }
104 else {
105 asuTwig.append("&-out.all=1");
106 }
107 }
108
109
110 public void visitFunction(Function function) {
111 throw new IllegalArgumentException("Only CIRCLE functions can be used");
112 }
113
114 /*** ASU can only handle flat comparisons (I believe) so check that the comparison is not nested */
115 public void visitNumericComparison(NumericComparison comparison) throws IOException {
116 if (!(comparison.getLHS() instanceof SearchFieldReference) || !(comparison.getRHS() instanceof Literal)) {
117 throw new IllegalArgumentException("Comparisons are restricted to {field}{condition}{literal} and should not be nested, but they are in "+comparison);
118 }
119 asuTwig.append("&");
120 comparison.getLHS().acceptVisitor(this);
121 if (comparison.getOperator()==NumericCompareOperator.NE) {
122 asuTwig.append("="+URLEncoder.encode("!="));
123 }
124 else {
125 asuTwig.append("="+URLEncoder.encode(comparison.getOperator().toString()));
126 }
127 comparison.getRHS().acceptVisitor(this);
128 }
129
130 public void visitStringComparison(StringComparison comparison) throws IOException {
131 if (!(comparison.getLHS() instanceof SearchFieldReference) || !(comparison.getRHS() instanceof Literal)) {
132 throw new IllegalArgumentException("Comparisons are restricted to {field}{condition}{literal} and should not be nested, but they are in "+comparison);
133 }
134 asuTwig.append("&");
135 comparison.getLHS().acceptVisitor(this);
136 if (comparison.getOperator()==StringCompareOperator.EQ) {
137 asuTwig.append("="+URLEncoder.encode("=="));
138 }
139 if (comparison.getOperator()==StringCompareOperator.NE) {
140 asuTwig.append("="+URLEncoder.encode("!="));
141 }
142 else if (comparison.getOperator()==StringCompareOperator.LIKE) {
143 asuTwig.append("="+URLEncoder.encode("="));
144 }
145 else {
146 asuTwig.append("="+URLEncoder.encode(comparison.getOperator().toString()));
147 }
148 comparison.getRHS().acceptVisitor(this);
149 }
150
151 public void visitScope(String[] scope) {
152 if ((scope ==null) || (scope.length==0)) {
153 return;
154 }
155 asuTwig.append("&-source="+scope[0]);
156 for (int i = 1; i < scope.length; i++)
157 {
158 asuTwig.append(","+scope[i]);
159 }
160 }
161
162 /*** returns twig, prepending ? and removing initial & and */
163 public String getAsuTwig() {
164 return "?"+asuTwig.toString().substring(1);
165 }
166
167 /***
168 *
169 */
170 public static void main(String[] args) throws IOException
171 {
172
173
174
175
176
177
178
179
180
181
182 Query query = SqlParser.makeQuery("SELECT ELIAS.RMAG, ELIAS.BMAG FROM ELAIS WHERE CIRCLE('J2000',20,30,6) AND ((ELIAS.RMAG > 5 OR ELIAS.BMAG >= 5) OR ELIAS.COOKED LIKE 'TRUE')");
183
184 AsuTwigMaker t = new AsuTwigMaker();
185
186 query.acceptVisitor(t);
187
188 System.out.println(t.getAsuTwig());
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