source: SRUServer/trunk/src/main/java/eu/clarin/sru/server/utils/SRUServerServlet.java @ 1990

Last change on this file since 1990 was 1990, checked in by oschonef, 12 years ago
  • add SRUServerServlet and SRUSearchEngineBase
  • add close() method to response objects
  • remove hasMore*() methods and modify next*() to return boolean from SRUScanResponse and SRUSearchResponse

HEADS UP:
This commit breaks existing API and requires changes to your SRUScanResponse and SRUSearchResponse implementations

File size: 10.4 KB
Line 
1/**
2 * This software is copyright (c) 2011 by
3 *  - Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
4 * This is free software. You can redistribute it
5 * and/or modify it under the terms described in
6 * the GNU General Public License v3 of which you
7 * should have received a copy. Otherwise you can download
8 * it from
9 *
10 *   http://www.gnu.org/licenses/gpl-3.0.txt
11 *
12 * @copyright Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
13 *
14 * @license http://www.gnu.org/licenses/gpl-3.0.txt
15 *  GNU General Public License v3
16 */
17package eu.clarin.sru.server.utils;
18
19import java.io.IOException;
20import java.lang.reflect.Constructor;
21import java.lang.reflect.InvocationTargetException;
22import java.net.MalformedURLException;
23import java.net.URL;
24import java.util.Enumeration;
25import java.util.HashMap;
26import java.util.Map;
27
28import javax.servlet.ServletConfig;
29import javax.servlet.ServletContext;
30import javax.servlet.ServletException;
31import javax.servlet.http.HttpServlet;
32import javax.servlet.http.HttpServletRequest;
33import javax.servlet.http.HttpServletResponse;
34
35import eu.clarin.sru.server.SRUConfigException;
36import eu.clarin.sru.server.SRUException;
37import eu.clarin.sru.server.SRUServer;
38import eu.clarin.sru.server.SRUServerConfig;
39
40
41/**
42 * A Servlet implementation, which provides an enviroment for running a
43 * {@link SRUServer} in a servlet container. Your search engine <b>must</b> use
44 * {@link SRUSearchEngineBase} as base class.
45 *
46 * <p>
47 * Add the following to the web.xml of your web applications web.xml to define a
48 * SRU server. Of couse, the value of the servlet paramter
49 * "sruServerSerachEngineClass" must be adpated to match the name of your search
50 * engine implementation. Furthermore, you can choose different url-pattern, to
51 * match your needs.
52 * </p>
53 *
54 * <pre>
55 * &lt;servlet&gt;
56 *   &lt;servlet-name&gt;SRUServerServlet&lt;/servlet-name&gt;
57 *   &lt;servlet-class&gt;eu.clarin.sru.server.utils.SRUServerServlet&lt;/servlet-class&gt;
58 *   &lt;init-param&gt;
59 *     &lt;param-name&gt;sruServerSerachEngineClass&lt;/param-name&gt;
60 *     &lt;param-value&gt;com.acme.MySearchEngine&lt;/param-value&gt;
61 *   &lt;/init-param&gt;
62 * &lt;/servlet&gt;
63 * &lt;servlet-mapping&gt;
64 *   &lt;servlet-name&gt;SRUServerServlet&lt;/servlet-name&gt;
65 *   &lt;url-pattern&gt;/sru&lt;/url-pattern&gt;
66 * &lt;/servlet-mapping&gt;
67 * </pre>
68 */
69public final class SRUServerServlet extends HttpServlet {
70    /**
71     * Servlet initialization parameter name for the location of the SRU server
72     * configuration.
73     */
74    public static final String SRU_SERVER_CONFIG_LOCATION_PARAM =
75            "sruServerConfigLocation";
76    /**
77     * Servlet initialization parameter name for the class that implements the
78     * SRU search engine.
79     */
80    public static final String SRU_SERVER_SERACH_ENGINE_CLASS_PARAM =
81            "sruServerSerachEngineClass";
82    /**
83     * Default value for the location of the SRU server configuration.
84     */
85    public static final String SRU_SERVER_CONFIG_LOCATION_DEFAULT =
86            "/WEB-INF/sru-server-config.xml";
87    private static final long serialVersionUID = 1L;
88    private SRUServer sruServer;
89    private SRUSearchEngineBase searchEngine;
90
91
92    /**
93     * Initialize the SRU server Servlet.
94     *
95     * @see javax.servlet.GenericServlet#init()
96     */
97    @Override
98    public void init() throws ServletException {
99        final ServletConfig cfg  = getServletConfig();
100        final ServletContext ctx = getServletContext();
101
102        String sruServerConfigLocation =
103                cfg.getInitParameter(SRU_SERVER_CONFIG_LOCATION_PARAM);
104        if (sruServerConfigLocation == null) {
105            sruServerConfigLocation = SRU_SERVER_CONFIG_LOCATION_DEFAULT;
106        }
107
108        URL sruServerConfigFile = null;
109        try {
110            sruServerConfigFile = ctx.getResource(sruServerConfigLocation);
111        } catch (MalformedURLException e) {
112            throw new ServletException("init parameter '" +
113                    SRU_SERVER_CONFIG_LOCATION_PARAM + "' is not a valid URL",
114                    e);
115        }
116        if (sruServerConfigFile == null) {
117            throw new ServletException("init parameter '" +
118                    SRU_SERVER_CONFIG_LOCATION_PARAM +
119                    "' points to non-existing resource (" +
120                    sruServerConfigLocation + ")");
121        }
122
123        String sruServerSearchEngineClass =
124                cfg.getInitParameter(SRU_SERVER_SERACH_ENGINE_CLASS_PARAM);
125        if (sruServerSearchEngineClass == null) {
126            throw new ServletException("init parameter '" +
127                    SRU_SERVER_SERACH_ENGINE_CLASS_PARAM +
128                    "' not defined in servlet configuration");
129        }
130
131        /*
132         * get init-parameters from ServletConfig ...
133         */
134        final HashMap<String, String> params = new HashMap<String, String>();
135        for (Enumeration<?> i = cfg.getInitParameterNames();
136                i.hasMoreElements();) {
137            String key = (String) i.nextElement();
138            String value = cfg.getInitParameter(key);
139            if ((value != null) && !value.isEmpty()) {
140                params.put(key, value);
141            }
142        }
143
144        /*
145         * ... and get more init-parameters from ServletContext and potentially
146         * overriding parameters from servlet configuration.
147         */
148        for (Enumeration<?> i = ctx.getInitParameterNames();
149                i.hasMoreElements();) {
150            String key = (String) i.nextElement();
151            String value = ctx.getInitParameter(key);
152            if ((value != null) && !value.isEmpty()) {
153                params.put(key, value);
154            }
155        }
156
157        /*
158         * Set some defaults (aka "plug and play" for development deployment)
159         * Override those for a production deployment through your Servlet
160         * container's context configuration!
161         */
162        setDefaultConfigParam(params, SRUServerConfig.SRU_TRANSPORT,
163                              "http");
164        setDefaultConfigParam(params, SRUServerConfig.SRU_HOST,
165                              "127.0.0.1");
166        setDefaultConfigParam(params, SRUServerConfig.SRU_PORT,
167                              "8080");
168        setDefaultConfigParam(params, SRUServerConfig.SRU_DATABASE,
169                              ctx.getContextPath());
170
171        // parse configuration
172        SRUServerConfig sruServerConfig = null;
173        try {
174            sruServerConfig =
175                    SRUServerConfig.parse(params, sruServerConfigFile);
176        } catch (SRUConfigException e) {
177            throw new ServletException("sru server configuration is invalid", e);
178        }
179
180        /*
181         * create an instance of the search engine ...
182         */
183        try {
184            @SuppressWarnings("unchecked")
185            Class<SRUSearchEngineBase> clazz = (Class<SRUSearchEngineBase>)
186                Class.forName(sruServerSearchEngineClass);
187            Constructor<SRUSearchEngineBase> constructor =
188                    clazz.getConstructor();
189            searchEngine = constructor.newInstance();
190        } catch (ClassNotFoundException e) {
191            throw new ServletException("error inisializing sru server", e);
192        } catch (ClassCastException e) {
193            throw new ServletException("error inisializing sru server", e);
194        } catch (NoSuchMethodException e) {
195            throw new ServletException("error inisializing sru server", e);
196        } catch (SecurityException e) {
197            throw new ServletException("error inisializing sru server", e);
198        } catch (InstantiationException e) {
199            throw new ServletException("error inisializing sru server", e);
200        } catch (IllegalAccessException e) {
201            throw new ServletException("error inisializing sru server", e);
202        } catch (IllegalArgumentException e) {
203            throw new ServletException("error inisializing sru server", e);
204        } catch (InvocationTargetException e) {
205            throw new ServletException("error inisializing sru server", e);
206        }
207
208        /*
209         * finally initialize the SRU server ...
210         */
211        try {
212            searchEngine.init(sruServerConfig, params);
213            sruServer = new SRUServer(sruServerConfig, searchEngine);
214        } catch (SRUConfigException e) {
215            throw new ServletException("error inisializing sru server", e);
216        } catch (SRUException e) {
217            throw new ServletException("error inisializing sru server", e);
218        }
219    }
220
221
222    /**
223     * Destroy the SRU server Servlet.
224     *
225     * @see javax.servlet.GenericServlet#destroy()
226     */
227    @Override
228    public void destroy() {
229        if (searchEngine != null) {
230            searchEngine.destroy();
231        }
232        super.destroy();
233    }
234
235
236    /**
237     * Handle a HTTP get request.
238     *
239     * @see
240     * javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest
241     * , javax.servlet.http.HttpServletResponse)
242     */
243    @Override
244    protected void doGet(HttpServletRequest request,
245            HttpServletResponse response) throws ServletException, IOException {
246        if (sruServer == null) {
247            throw new ServletException("servlet is not properly initalized");
248        }
249        sruServer.handleRequest(request, response);
250    }
251
252
253    /**
254     * Handle a HTTP post request.
255     *
256     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest,
257     *      javax.servlet.http.HttpServletResponse)
258     */
259    @Override
260    protected void doPost(HttpServletRequest request,
261            HttpServletResponse response) throws ServletException, IOException {
262        if (sruServer == null) {
263            throw new ServletException("servlet is not properly initalized");
264        }
265        sruServer.handleRequest(request, response);
266    }
267
268
269    private void setDefaultConfigParam(Map<String, String> params, String key,
270            String value) {
271        if (!params.containsKey(key)) {
272            params.put(key, value);
273            log("NOTE: using default '" + value + "' for parameter '" + key +
274                    "', because it was not defined in context configuration.");
275            log("THIS IS NOT RECOMMENDED FOR PRODUCTION DEPLOYMENT!");
276        }
277    }
278
279} // class SRUServerServlet
Note: See TracBrowser for help on using the repository browser.