View Javadoc

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  //package ORG.oclc.oai.server;
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  // import org.apache.log4j.BasicConfigurator;
63  // import org.apache.log4j.Logger;
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  //     private static Logger logger = Logger.getLogger(OAIHandler.class);
83  //     static {
84  //         BasicConfigurator.configure();
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 	    }//while
115 	    //FileInputStream in = new FileInputStream(fileName);
116        System.out.println("the filename = " + fileName);
117        URL configUrl = this.getClass().getClassLoader().getResource(fileName);       
118 	    Properties properties = new Properties();
119 	    //properties.load(in);
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 //         try {
189             //request.setCharacterEncoding("UTF-8");
190 //         } catch (UnsupportedEncodingException e) {
191 //             e.printStackTrace();
192 //             throw new IOException(e.getMessage());
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                     // return HTML if the client is an old browser
221                     if (this.forceRender
222 			|| userAgent.indexOf("opera") != -1
223 			|| (userAgent.startsWith("mozilla")
224 			    && userAgent.indexOf("msie 6") == -1
225                         /* && userAgent.indexOf("netscape/7") == -1 */)) {
226                         serverTransformer = transformer;
227                     }
228                 }
229 		String result = getResult(attributes, request, response, serverTransformer, serverVerbs, extensionVerbs, extensionPath);
230 //                 logger.debug("result=" + result);
231                 
232 //                 if (serverTransformer) { // render on the server
233 //                     response.setContentType("text/html; charset=UTF-8");
234 //                     StringReader stringReader = new StringReader(getResult(request));
235 //                     StreamSource streamSource = new StreamSource(stringReader);
236 //                     StringWriter stringWriter = new StringWriter();
237 //                     transformer.transform(streamSource, new StreamResult(stringWriter));
238 //                     result = stringWriter.toString();
239 //                 } else { // render on the client
240 //                     response.setContentType("text/xml; charset=UTF-8");
241 //                     result = getResult(request);
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 //  	    System.out.println("using gzip encoding");
345 //             logger.debug("using gzip encoding");
346 	    response.setHeader("Content-Encoding", "gzip");
347 	    out = new OutputStreamWriter(new GZIPOutputStream(response.getOutputStream()),
348 					 "UTF-8");
349 // 	} else if (encodings != null && encodings.indexOf("compress") != -1) {
350 // //  	    System.out.println("using compress encoding");
351 // 	    response.setHeader("Content-Encoding", "compress");
352 // 	    ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
353 // 	    zos.putNextEntry(new ZipEntry("dummy name"));
354 // 	    out = new OutputStreamWriter(zos, "UTF-8");
355 	} else if (encodings != null && encodings.indexOf("deflate") != -1) {
356 //  	    System.out.println("using deflate encoding");
357 //             logger.debug("using deflate encoding");
358 	    response.setHeader("Content-Encoding", "deflate");
359 	    out = new OutputStreamWriter(new DeflaterOutputStream(response.getOutputStream()),
360 					 "UTF-8");
361 	} else {
362 //             logger.debug("using no encoding");
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 }