1
2 /***
3 *Copyright (c) 2000-2002 OCLC Online Computer Library Center,
4 *Inc. and other contributors. All rights reserved. The contents of this file, as updated
5 *from time to time by the OCLC Office of Research, are subject to OCLC Research
6 *Public License Version 2.0 (the "License"); you may not use this file except in
7 *compliance with the License. You may obtain a current copy of the License at
8 *http://purl.oclc.org/oclc/research/ORPL/. Software distributed under the License is
9 *distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
10 *or implied. See the License for the specific language governing rights and limitations
11 *under the License. This software consists of voluntary contributions made by many
12 *individuals on behalf of OCLC Research. For more information on OCLC Research,
13 *please see http://www.oclc.org/oclc/research/.
14 *
15 *The Original Code is OAIHandler.java.
16 *The Initial Developer of the Original Code is Jeff Young.
17 *Portions created by ______________________ are
18 *Copyright (C) _____ _______________________. All Rights Reserved.
19 *Contributor(s):______________________________________.
20 */
21
22
23
24 package astrogrid.registry.oai;
25
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.io.OutputStreamWriter;
30 import java.io.StringReader;
31 import java.io.StringWriter;
32 import java.io.Writer;
33 import java.lang.IllegalAccessException;
34 import java.lang.NoSuchMethodException;
35 import java.lang.reflect.Constructor;
36 import java.lang.reflect.Method;
37 import java.lang.reflect.InvocationTargetException;
38 import java.util.Date;
39 import java.util.HashMap;
40 import java.util.Properties;
41 import java.util.Enumeration;
42 import java.util.zip.DeflaterOutputStream;
43 import java.util.zip.GZIPOutputStream;
44 import java.util.zip.ZipOutputStream;
45 import java.util.zip.ZipEntry;
46 import javax.servlet.ServletConfig;
47 import javax.servlet.ServletContext;
48 import javax.servlet.ServletException;
49 import javax.servlet.SingleThreadModel;
50 import javax.servlet.http.HttpServlet;
51 import javax.servlet.http.HttpServletRequest;
52 import javax.servlet.http.HttpServletResponse;
53 import javax.xml.transform.stream.StreamResult;
54 import javax.xml.transform.stream.StreamSource;
55 import javax.xml.transform.Transformer;
56 import javax.xml.transform.TransformerException;
57 import javax.xml.transform.TransformerFactory;
58 import ORG.oclc.oai.server.catalog.AbstractCatalog;
59 import ORG.oclc.oai.server.verb.*;
60 import java.net.URL;
61
62
63
64
65 /***
66 * OAIHandler is the primary Servlet for OAICat.
67 *
68 * @author Jeffrey A. Young, OCLC Online Computer Library Center
69 */
70 public class OAIHandler extends HttpServlet {
71 private static final String VERSION = "1.5.26";
72 private Transformer transformer = null;
73 private static boolean debug = false;
74 private boolean serviceUnavailable = false;
75 private boolean monitor = false;
76 private boolean forceRender = false;
77 private HashMap attributes = null;
78 private HashMap serverVerbs = null;
79 private HashMap extensionVerbs = null;
80 private String extensionPath = null;
81
82
83
84
85
86
87 /***
88 * Get the VERSION number
89 */
90 public static String getVERSION() { return VERSION; }
91
92 /***
93 * init is called one time when the Servlet is loaded. This is the
94 * place where one-time initialization is done. Specifically, we
95 * load the properties file for this application, and create the
96 * AbstractCatalog object for subsequent use.
97 *
98 * @param config servlet configuration information
99 * @exception ServletException there was a problem with initialization
100 */
101 public void init(ServletConfig config) throws ServletException {
102 super.init(config);
103 String fileName =
104 config.getServletContext().getInitParameter("properties");
105 String versionNumber =
106 config.getInitParameter("registry_version");
107 try {
108 ServletContext context = getServletContext();
109 attributes = new HashMap();
110 Enumeration attrNames = context.getAttributeNames();
111 while (attrNames.hasMoreElements()) {
112 String attrName = (String)attrNames.nextElement();
113 attributes.put(attrName, context.getAttribute(attrName));
114 }
115
116 System.out.println("the filename = " + fileName);
117 URL configUrl = this.getClass().getClassLoader().getResource(fileName);
118 Properties properties = new Properties();
119
120 properties.load(configUrl.openStream());
121 properties.setProperty("registry_version",versionNumber);
122 attributes.put("OAIHandler.properties", properties);
123
124 String temp = properties.getProperty("OAIHandler.debug");
125 System.out.println("is debug turned on = " + temp);
126 if ("true".equals(temp)) debug = true;
127 extensionPath = properties.getProperty("OAIHandler.extensionPath", "/extension");
128 if (debug)
129 System.out.println("OAIHandler.init: fileName=" + fileName);
130 if (properties.getProperty("OAIHandler.serviceUnavailable") != null) {
131 this.serviceUnavailable = true;
132 } else {
133 attributes.put("OAIHandler.version", VERSION);
134 AbstractCatalog abstractCatalog = AbstractCatalog.factory(properties);
135 attributes.put("OAIHandler.catalog", abstractCatalog);
136 }
137 if (properties.getProperty("OAIHandler.monitor") != null) {
138 this.monitor = true;
139 }
140 if ("true".equals(properties.getProperty("OAIHandler.forceRender"))) {
141 this.forceRender = true;
142 }
143 String xsltName = properties.getProperty("OAIHandler.styleSheet");
144 String appBase = properties.getProperty("OAIHandler.appBase");
145 if (appBase == null) appBase = "webapps";
146 if (xsltName != null
147 && ("true".equalsIgnoreCase(properties.getProperty("OAIHandler.renderForOldBrowsers"))
148 || this.forceRender)) {
149 StreamSource xslSource = new StreamSource(new FileInputStream(appBase + "/"
150 + xsltName));
151 TransformerFactory tFactory = TransformerFactory.newInstance();
152 transformer = tFactory.newTransformer(xslSource);
153 }
154
155 serverVerbs = ServerVerb.getVerbs(properties);
156 extensionVerbs = ServerVerb.getExtensionVerbs(properties);
157 } catch (FileNotFoundException e) {
158 e.printStackTrace();
159 throw new ServletException(e.getMessage());
160 } catch (ClassNotFoundException e) {
161 e.printStackTrace();
162 throw new ServletException(e.getMessage());
163 } catch (IllegalArgumentException e) {
164 e.printStackTrace();
165 throw new ServletException(e.getMessage());
166 } catch (IOException e) {
167 e.printStackTrace();
168 throw new ServletException(e.getMessage());
169 } catch (Throwable e) {
170 e.printStackTrace();
171 throw new ServletException(e.getMessage());
172 }
173 }
174
175 /***
176 * Peform the http GET action. Note that POST is shunted to here as well.
177 * The verb widget is taken from the request and used to invoke an
178 * OAIVerb object of the corresponding kind to do the actual work of the verb.
179 *
180 * @param request the servlet's request information
181 * @param response the servlet's response information
182 * @exception ServletException a servlet error occurred
183 * @exception IOException an I/O error occurred
184 */
185 public void doGet(HttpServletRequest request,
186 HttpServletResponse response)
187 throws ServletException, IOException {
188
189
190
191
192
193
194 Date then = null;
195 if (monitor) then = new Date();
196 if (debug) {
197 Enumeration headerNames = request.getHeaderNames();
198 System.out.println("OAIHandler.doGet: ");
199 while (headerNames.hasMoreElements()) {
200 String headerName = (String)headerNames.nextElement();
201 System.out.print(headerName);
202 System.out.print(": ");
203 System.out.println(request.getHeader(headerName));
204 }
205 }
206 if (serviceUnavailable) {
207 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
208 "Sorry. This server is down for maintenance");
209 } else {
210 try {
211 String userAgent = request.getHeader("User-Agent");
212 if (userAgent == null) {
213 userAgent = "";
214 } else {
215 userAgent = userAgent.toLowerCase();
216 }
217 Transformer serverTransformer = null;
218 if (transformer != null) {
219
220
221 if (this.forceRender
222 || userAgent.indexOf("opera") != -1
223 || (userAgent.startsWith("mozilla")
224 && userAgent.indexOf("msie 6") == -1
225
226 serverTransformer = transformer;
227 }
228 }
229 String result = getResult(attributes, request, response, serverTransformer, serverVerbs, extensionVerbs, extensionPath);
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244 Writer out = getWriter(request, response);
245 out.write(result);
246 out.close();
247 } catch (FileNotFoundException e) {
248 if (debug) {
249 e.printStackTrace();
250 System.out.println("SC_NOT_FOUND: " + e.getMessage());
251 }
252 response.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
253 } catch (TransformerException e) {
254 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
255 } catch (OAIInternalServerError e) {
256 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
257 } catch (Throwable e) {
258 e.printStackTrace();
259 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
260 }
261 }
262 if (monitor) {
263 System.out.println(request.getHeader("Accept-Encoding") + ": " + ((new Date()).getTime()-then.getTime()) + "ms: "
264 + request.getQueryString());
265 }
266 }
267
268 public static String getResult(HashMap attributes,
269 HttpServletRequest request,
270 HttpServletResponse response,
271 Transformer serverTransformer,
272 HashMap serverVerbs,
273 HashMap extensionVerbs,
274 String extensionPath)
275 throws Throwable {
276 try {
277 boolean isExtensionVerb = extensionPath.equals(request.getPathInfo());
278 String verb = request.getParameter("verb");
279 if (debug) {
280 System.out.println("OAIHandler.getResult: verb=>" + verb + "<");
281 }
282 String result;
283 Class verbClass = null;
284 if (isExtensionVerb) {
285 verbClass = (Class)extensionVerbs.get(verb);
286 } else {
287 verbClass = (Class)serverVerbs.get(verb);
288 }
289 if (verbClass == null) {
290 if (debug) {
291 System.out.println("verb not found among:");
292 java.util.Iterator keySet = null;
293 if (isExtensionVerb) {
294 keySet = extensionVerbs.keySet().iterator();
295 } else {
296 keySet = serverVerbs.keySet().iterator();
297 }
298 while(keySet.hasNext()) {
299 System.out.println(keySet.next());
300 }
301 }
302 result=BadVerb.construct(attributes, request, response, serverTransformer);
303 } else {
304 Method construct = verbClass.getMethod("construct",
305 new Class[] {HashMap.class,
306 HttpServletRequest.class,
307 HttpServletResponse.class,
308 Transformer.class});
309 try {
310 result = (String)construct.invoke(null,
311 new Object[] {attributes,
312 request,
313 response,
314 serverTransformer});
315 } catch (InvocationTargetException e) {
316 throw e.getTargetException();
317 }
318 }
319 if (debug) {
320 System.out.println(result);
321 }
322 return result;
323 } catch (NoSuchMethodException e) {
324 throw new OAIInternalServerError(e.getMessage());
325 } catch (IllegalAccessException e) {
326 throw new OAIInternalServerError(e.getMessage());
327 }
328 }
329
330 /***
331 * Get a response Writer depending on acceptable encodings
332 * @param request the servlet's request information
333 * @param response the servlet's response information
334 * @exception IOException an I/O error occurred
335 */
336 public static Writer getWriter(HttpServletRequest request, HttpServletResponse response)
337 throws IOException {
338 Writer out;
339 String encodings = request.getHeader("Accept-Encoding");
340 if (debug) {
341 System.out.println("encodings=" + encodings);
342 }
343 if (encodings != null && encodings.indexOf("gzip") != -1) {
344
345
346 response.setHeader("Content-Encoding", "gzip");
347 out = new OutputStreamWriter(new GZIPOutputStream(response.getOutputStream()),
348 "UTF-8");
349
350
351
352
353
354
355 } else if (encodings != null && encodings.indexOf("deflate") != -1) {
356
357
358 response.setHeader("Content-Encoding", "deflate");
359 out = new OutputStreamWriter(new DeflaterOutputStream(response.getOutputStream()),
360 "UTF-8");
361 } else {
362
363 out = response.getWriter();
364 }
365 return out;
366 }
367
368 /***
369 * Peform a POST action. Actually this gets shunted to GET
370 *
371 * @param request the servlet's request information
372 * @param response the servlet's response information
373 * @exception ServletException a servlet error occurred
374 * @exception IOException an I/O error occurred
375 */
376 public void doPost(HttpServletRequest request,
377 HttpServletResponse response)
378 throws ServletException, IOException {
379 doGet(request, response);
380 }
381 }