1
2
3
4
5
6
7 package org.astrogrid.dataservice.service;
8
9 import java.io.IOException;
10 import java.io.PrintWriter;
11 import java.io.StringWriter;
12 import java.net.MalformedURLException;
13 import java.net.URISyntaxException;
14 import java.net.URL;
15 import java.security.Principal;
16 import javax.servlet.http.HttpServletRequest;
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19 import org.astrogrid.account.LoginAccount;
20 import org.astrogrid.cfg.ConfigFactory;
21 import org.astrogrid.query.condition.CircleCondition;
22 import org.astrogrid.query.returns.ReturnImage;
23 import org.astrogrid.query.returns.ReturnSpec;
24 import org.astrogrid.query.returns.ReturnTable;
25 import org.astrogrid.slinger.mime.MimeNames;
26 import org.astrogrid.slinger.targets.TargetMaker;
27
28 /***
29 * A set of dataserver methods for helping serving data in HTML form, eg for servlets
30 * or JSPs
31 * <p>
32 * @author M Hill
33 */
34
35 public class ServletHelper
36 {
37
38 protected static Log log = LogFactory.getLog(ServletHelper.class);
39
40 private static String urlStem = null;
41
42 public static void setUrlStem(String aStem) {
43 if (!aStem.endsWith("/")) {
44 aStem = aStem+"/";
45 }
46
47 try {
48 new URL(aStem).openStream();
49 }
50 catch (IOException e) {
51 log.error("URL stem "+aStem+" is invalid or unreachable ("+e+")");
52 return;
53 }
54
55 log.info("Service Stem set to '"+aStem+"'");
56 if (urlStem == null) {
57 urlStem = aStem;
58 }
59 else if (!urlStem.equals(aStem)) {
60 log.error("Trying to set service URL stem to "+aStem+" when already "+urlStem+"; ignoring new stem");
61 }
62 }
63
64 /*** Provides static access to the url stem (eg http://grendel12.roe.ac.uk/pal-6df)" target="alexandria_uri">http://grendel12.roe.ac.uk/pal-6df) */
65 public static String getUrlStem() {
66 if (urlStem != null) {
67 return urlStem;
68 }
69
70 if (AxisDataServer.getMessageContextUrlStem() != null) {
71 setUrlStem(AxisDataServer.getMessageContextUrlStem());
72 return urlStem;
73 }
74
75 if (getRequestUrlStem() != null) {
76 setUrlStem(getRequestUrlStem());
77 return urlStem;
78 }
79
80
81 String configStem = ConfigFactory.getCommonConfig().getString("datacenter.url");
82 if (configStem != null) {
83 if (!configStem.endsWith("/")) {
84 configStem = configStem+"/";
85 }
86 }
87 return configStem;
88 }
89
90 public static String getRequestUrlStem() {
91 return null;
92 }
93
94 public static String getUrlStem(HttpServletRequest request) {
95 return request.getScheme()+"://"+request.getServerName() +":" + request.getServerPort()+request.getContextPath();
96 }
97
98 /***
99 * Gets the user details from the request */
100 public static Principal getUser(HttpServletRequest request) {
101 if (request.getParameter("UserName") != null) {
102
103 return new LoginAccount(request.getParameter("UserName"), "Unknown");
104 }
105 else {
106 return LoginAccount.ANONYMOUS;
107 }
108 }
109
110 /***
111 * Convenience routine for JSPs; decides where target should be from
112 * the parameters in the given request. The parameter names should match
113 * those assigned in resultsForm.xml */
114 public static ReturnSpec makeReturnSpec(HttpServletRequest request) {
115
116 ReturnSpec returnSpec = null;
117
118 String format = request.getParameter("Format");
119 if ( (format != null) && (format.trim().length()>0)) {
120 if (ReturnImage.isImageFormat(new String[] { format })) {
121 returnSpec = new ReturnImage(null);
122 }
123 }
124
125 if (returnSpec == null) {
126 returnSpec = new ReturnTable(null);
127 }
128
129 fillReturnSpec(returnSpec, request);
130
131 return returnSpec;
132 }
133
134 /***
135 * Convenience routine for JSPs; returns true if this is an 'ask count' request
136 * from the resultsForm.xml */
137 public static boolean isCountReq(HttpServletRequest request) {
138 String format = request.getParameter("Format");
139 if ( (format != null) && (format.trim().length()>0) && (format.trim().toLowerCase().equals("count"))) {
140 return true;
141 }
142 else {
143 return false;
144 }
145 }
146
147 /***
148 * Convenience routine for JSPs; decides where target should be from
149 * the parameters in the given request. The parameter names should match
150 * those assigned in resultsForm.xml */
151 public static void fillReturnSpec(ReturnSpec returnSpec, HttpServletRequest request) {
152
153 String targetResponse = request.getParameter("TargetResponse");
154 if ((targetResponse != null) && targetResponse.trim().toLowerCase().equals("true")) {
155
156 returnSpec.setTarget(null);
157 }
158 else {
159 String targetUri = request.getParameter("TargetURI");
160 if ((targetUri != null) && (targetUri.trim().length()>0)) {
161
162 try {
163 returnSpec.setTarget(TargetMaker.makeTarget(targetUri));
164 }
165 catch (URISyntaxException e) {
166 throw new IllegalArgumentException("Invalid target: "+targetUri+" ("+e+")");
167 }
168 catch (IOException e) {
169 throw new IllegalArgumentException("Invalid target: "+targetUri+" ("+e+")");
170 }
171 }
172 else {
173
174
175 returnSpec.setTarget(null);
176 }
177 }
178
179 String format = request.getParameter("Format");
180 if ( (format != null) && (format.trim().length()>0)) {
181 returnSpec.setFormat(format);
182 }
183
184 String compression = request.getParameter("Compression");
185 if ( (compression != null) && (compression.trim().length()>0)) {
186 returnSpec.setCompression(compression);
187 }
188
189 String limit = request.getParameter("Limit");
190 if ( (limit != null) && (limit.trim().length()>0)) {
191 returnSpec.setLimit(Integer.parseInt(limit));
192 }
193
194 }
195
196 /*** Creates a Circle function condition from parameters in the given request.
197 * Accepts POS=(ra,dec) and RA=ra&DEC=dec, and SIZE and SR for search radius.
198 * Accepts all-lower case as well as all-upper case
199 */
200 public static CircleCondition makeCircleCondition(HttpServletRequest request) {
201
202 String radiusparam = request.getParameter("SIZE");
203 if (radiusparam == null) { radiusparam = request.getParameter("size"); }
204 if (radiusparam == null) { radiusparam = request.getParameter("SR"); }
205 if (radiusparam == null) { radiusparam = request.getParameter("sr"); }
206 if (radiusparam == null) { radiusparam = request.getParameter("RADIUS"); }
207 if (radiusparam == null) { radiusparam = request.getParameter("radius"); }
208 if (radiusparam == null) {
209 throw new IllegalArgumentException("No Radius given as SIZE or SR or RADIUS");
210 }
211 double radius = Double.parseDouble(radiusparam);
212
213 double ra;
214 double dec;
215
216 String pos = request.getParameter("POS");
217 if (pos == null) { request.getParameter("pos"); }
218 if (pos != null) {
219 int comma = pos.indexOf(",");
220 ra = Double.parseDouble(pos.substring(0,comma));
221 dec = Double.parseDouble(pos.substring(comma+1));
222 return new CircleCondition(ra, dec, radius);
223 }
224
225 String raparam = request.getParameter("RA");
226 if (raparam == null) { raparam = request.getParameter("ra"); }
227 if (raparam == null) { raparam = request.getParameter("Ra"); }
228 if (raparam == null) {
229 throw new IllegalArgumentException("No RA given");
230 }
231
232 String decparam = request.getParameter("DEC");
233 if (decparam == null) { decparam = request.getParameter("dec"); }
234 if (decparam == null) { decparam = request.getParameter("Dec"); }
235 if (raparam == null) {
236 throw new IllegalArgumentException("No DEC given");
237 }
238
239 ra = Double.parseDouble(raparam);
240 dec = Double.parseDouble(decparam);
241
242 return new CircleCondition(ra, dec, radius);
243 }
244
245
246 /*** Convenience routine for returning the correct 'HTML' snippet that
247 * refreshes the page given by the URL - which should point to the same page
248 * that contains the snippet */
249 public static String makeRefreshSnippet(int secs, String url) {
250 return("(Refreshes every "+secs+" seconds)"+
251 "<META HTTP-EQUIV='Refresh' CONTENT='"+secs+";URL="+url+"'>");
252 }
253
254 /*** Returns the stylesheet to be used for the center's html pages in the form
255 * of a 'link' element. Returns an empty string if none configured */
256 public static String getCssLink() {
257 String cssName = ConfigFactory.getCommonConfig().getString("datacenter.stylesheet", "default.css");
258 if (cssName.length() == 0) {
259 return "";
260 }
261 else {
262 return "<LINK href='"+cssName+"' rel='stylesheet' type='text/css'>";
263 }
264 }
265
266 /*** Convenience routine that returns the complete <HEAD> element for the
267 * standard datacenter page */
268 public static String getHeadElement(String title) {
269 return "<HEAD>\n"+
270 " <TITLE>"+title+" ("+DataServer.getDatacenterName()+")</TITLE>\n"+
271 " "+getCssLink()+"\n"+
272 "</HEAD>\n";
273 }
274
275
276 /*** Retruns the available formats as a list of <option>format</option>
277 * in a single string */
278 public static String getFormatOptions() throws IOException {
279 String f[] = DataServer.getFormats();
280
281 String ops = "";
282 for (int i = 0; i < f.length; i++) {
283 ops = ops + "<option>"+MimeNames.humanFriendly(f[i])+"</option>";
284 }
285 return ops;
286 }
287
288 /***
289 * Returns an error as string suitable for display in a browser as an html
290 * page
291 */
292 public static String exceptionAsHtmlPage(String title, Throwable th, String details) {
293 return
294 "<html>\n"+
295 "<head><title>ERROR: "+makeSafeForHtml(title)+"</title></head>\n"+
296 "<body>\n"+
297 exceptionAsHtml(title, th, details)+
298 "</body>\n"+
299 "</html>\n";
300 }
301
302 /*** Returns exception suitable for a paragraph in an hmtl page */
303 public static String exceptionAsHtml(String title, Throwable th, String details) {
304
305 String s =
306 "<h1>ERROR REPORT</h1>\n";
307
308 if (th != null) {
309 s=s+
310 "<h2>"+makeSafeForHtml(th.getMessage())+"</h2>\n";
311 }
312 s =s + "<p>"+title+"</p>\n";
313
314 if (th != null) {
315 StringWriter sw = new StringWriter();
316 th.printStackTrace(new PrintWriter(sw));
317 String stack = sw.toString();
318
319 s = s +
320 "<p><b>"+makeSafeForHtml(th.toString())+"</b></p>\n"+
321 "<p>\n"+
322 "<pre>"+makeSafeForHtml(stack)+"</pre>\n"+
323 "</p>\n"+
324 "<p>\n";
325 }
326
327 s=s+
328 "<pre>"+makeSafeForHtml(details)+"</pre>\n"+
329 "</p>\n";
330
331 return s;
332 }
333
334 /***
335 * Deals with special characters */
336 public static String makeSafeForHtml(String s) {
337 if (s==null) {
338 return "";
339 }
340 s = s.replaceAll(">", ">").replaceAll("<", "<");
341 return s.replaceAll("\n","<br/>");
342 }
343
344 /*** Convenience routine for exceptionAsHtml(String, Exception, String) */
345 public static String exceptionAsHtmlPage(String title, Throwable th) {
346 return exceptionAsHtmlPage(title, th, "");
347 }
348
349 /*** For quick tests/debugging */
350 public static void main(String[] args) throws IOException
351 {
352 String t = getFormatOptions();
353 System.out.println(t);
354 }
355 }
356
357
358
359
360
361
362
363
364
365
366
367