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

Last change on this file since 6781 was 6781, checked in by Oliver Schonefeld, 9 years ago
  • remove legacy/deprecated Servlet context parameters (2)
File size: 12.0 KB
Line 
1/**
2 * This software is copyright (c) 2011-2013 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 org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
37
38import eu.clarin.sru.server.SRUConfigException;
39import eu.clarin.sru.server.SRUException;
40import eu.clarin.sru.server.SRUServer;
41import eu.clarin.sru.server.SRUServerConfig;
42
43
44/**
45 * A Servlet implementation, which provides an environment for running a
46 * {@link SRUServer} in a Servlet container. Your search engine <b>must</b> use
47 * {@link SRUSearchEngineBase} as base class.
48 *
49 * <p>
50 * Add the following to the web.xml of your web applications web.xml to define a
51 * SRU server. Of course, the value of the Servlet initialization parameter
52 * "eu.clarin.sru.server.utils.sruServerSearchEngineClass" must be adapted to
53 * match the name of your search engine implementation. Furthermore, you can
54 * choose different url-pattern, to match your needs.
55 * </p>
56 *
57 * <p>
58 * For example, if your implementation of {@link SRUSearchEngineBase} is
59 * "com.acme.MySearchEngine" and you want to map the Servlet to the URI "/sru"
60 * the following snippet in your "web.xml" should accomplish the task:
61 * </p>
62 *
63 * <pre>
64 * &lt;servlet&gt;
65 *   &lt;servlet-name&gt;SRUServerServlet&lt;/servlet-name&gt;
66 *   &lt;servlet-class&gt;eu.clarin.sru.server.utils.SRUServerServlet&lt;/servlet-class&gt;
67 *   &lt;init-param&gt;
68 *     &lt;param-name&gt;eu.clarin.sru.server.utils.sruServerSearchEngineClass&lt;/param-name&gt;
69 *     &lt;param-value&gt;com.acme.MySearchEngine&lt;/param-value&gt;
70 *   &lt;/init-param&gt;
71 * &lt;/servlet&gt;
72 * &lt;servlet-mapping&gt;
73 *   &lt;servlet-name&gt;SRUServerServlet&lt;/servlet-name&gt;
74 *   &lt;url-pattern&gt;/sru&lt;/url-pattern&gt;
75 * &lt;/servlet-mapping&gt;
76 * </pre>
77 */
78public final class SRUServerServlet extends HttpServlet {
79    /**
80     * Servlet initialization parameter name for the location of the SRU server
81     * configuration.
82     */
83    public static final String SRU_SERVER_CONFIG_LOCATION_PARAM =
84            "eu.clarin.sru.server.utils.sruServerConfigLocation";
85    /**
86     * Servlet initialization parameter name for the class that implements the
87     * SRU search engine.
88     */
89    public static final String SRU_SERVER_SEARCH_ENGINE_CLASS_PARAM =
90            "eu.clarin.sru.server.utils.sruServerSearchEngineClass";
91    /**
92     * Default value for the location of the SRU server configuration.
93     */
94    public static final String SRU_SERVER_CONFIG_LOCATION_DEFAULT =
95            "/WEB-INF/sru-server-config.xml";
96    private static final long serialVersionUID = 1L;
97    private static final Logger logger =
98            LoggerFactory.getLogger(SRUServerServlet.class);
99    private SRUServer sruServer;
100    private SRUSearchEngineBase searchEngine;
101
102
103    /**
104     * Initialize the SRU server Servlet.
105     *
106     * @see javax.servlet.GenericServlet#init()
107     */
108    @Override
109    public void init() throws ServletException {
110        final ServletConfig cfg  = getServletConfig();
111        final ServletContext ctx = getServletContext();
112
113        String sruServerConfigLocation =
114                cfg.getInitParameter(SRU_SERVER_CONFIG_LOCATION_PARAM);
115        if (sruServerConfigLocation == null) {
116            sruServerConfigLocation = SRU_SERVER_CONFIG_LOCATION_DEFAULT;
117        }
118
119        URL sruServerConfigFile;
120        try {
121            sruServerConfigFile = ctx.getResource(sruServerConfigLocation);
122        } catch (MalformedURLException e) {
123            throw new ServletException("init-parameter '" +
124                    SRU_SERVER_CONFIG_LOCATION_PARAM + "' is not a valid URL",
125                    e);
126        }
127        if (sruServerConfigFile == null) {
128            throw new ServletException("init-parameter '" +
129                    SRU_SERVER_CONFIG_LOCATION_PARAM +
130                    "' points to non-existing resource (" +
131                    sruServerConfigLocation + ")");
132        }
133
134        /* get search engine class name from Servlet init-parameters */
135        String sruServerSearchEngineClass =
136                cfg.getInitParameter(SRU_SERVER_SEARCH_ENGINE_CLASS_PARAM);
137        if (sruServerSearchEngineClass == null) {
138            throw new ServletException("init-parameter '" +
139                    SRU_SERVER_SEARCH_ENGINE_CLASS_PARAM +
140                    "' not defined in servlet configuration");
141        }
142
143        /*
144         * get init-parameters from ServletConfig ...
145         */
146        final HashMap<String, String> params = new HashMap<String, String>();
147        for (Enumeration<?> i = cfg.getInitParameterNames();
148                i.hasMoreElements();) {
149            String key = (String) i.nextElement();
150            String value = cfg.getInitParameter(key);
151            if ((value != null) && !value.isEmpty()) {
152                params.put(key, value);
153            }
154        }
155
156        /*
157         * ... and get more init-parameters from ServletContext and potentially
158         * overriding parameters from Servlet configuration.
159         */
160        for (Enumeration<?> i = ctx.getInitParameterNames();
161                i.hasMoreElements();) {
162            String key = (String) i.nextElement();
163            String value = ctx.getInitParameter(key);
164            if ((value != null) && !value.isEmpty()) {
165                params.put(key, value);
166            }
167        }
168
169        /*
170         * Set some defaults (aka "plug and play" for development deployment)
171         * Override those for a production deployment through your Servlet
172         * container's context configuration!
173         */
174        if (!params.containsKey(SRUServerConfig.SRU_TRANSPORT)) {
175            setDefaultConfigParam(params, SRUServerConfig.SRU_TRANSPORT,
176                    "http");
177        }
178        if (!params.containsKey(SRUServerConfig.SRU_HOST)) {
179            setDefaultConfigParam(params, SRUServerConfig.SRU_HOST,
180                    "127.0.0.1");
181        }
182        if (!params.containsKey(SRUServerConfig.SRU_PORT)) {
183            setDefaultConfigParam(params, SRUServerConfig.SRU_PORT,
184                    "8080");
185        }
186        if (!params.containsKey(SRUServerConfig.SRU_DATABASE)) {
187            String contextPath;
188            try {
189                /*
190                 * this only works with Servlet 2.5 API ...
191                 */
192                contextPath = ctx.getContextPath();
193            } catch (NoSuchMethodError e) {
194                /*
195                 * if we fail, put at least something here ...
196                 */
197                contextPath = "/";
198                log("NOTE: auto-configuration for parameter '" +
199                        SRUServerConfig.SRU_DATABASE +
200                        "' failed and will contain only a dummy value!");
201            }
202            setDefaultConfigParam(params, SRUServerConfig.SRU_DATABASE,
203                    contextPath);
204        }
205
206        // parse configuration
207        SRUServerConfig sruServerConfig;
208        try {
209            sruServerConfig =
210                    SRUServerConfig.parse(params, sruServerConfigFile);
211        } catch (SRUConfigException e) {
212            throw new ServletException("sru server configuration is invalid", e);
213        }
214
215        /*
216         * create an instance of the search engine ...
217         */
218        try {
219            logger.debug("creating new serach engine from class {}",
220                    sruServerSearchEngineClass);
221            @SuppressWarnings("unchecked")
222            Class<SRUSearchEngineBase> clazz = (Class<SRUSearchEngineBase>)
223                Class.forName(sruServerSearchEngineClass);
224            Constructor<SRUSearchEngineBase> constructor =
225                    clazz.getConstructor();
226            searchEngine = constructor.newInstance();
227        } catch (ClassNotFoundException e) {
228            throw new ServletException("error initializing sru server", e);
229        } catch (ClassCastException e) {
230            throw new ServletException("error initializing sru server", e);
231        } catch (NoSuchMethodException e) {
232            throw new ServletException("error initializing sru server", e);
233        } catch (SecurityException e) {
234            throw new ServletException("error initializing sru server", e);
235        } catch (InstantiationException e) {
236            throw new ServletException("error initializing sru server", e);
237        } catch (IllegalAccessException e) {
238            throw new ServletException("error initializing sru server", e);
239        } catch (IllegalArgumentException e) {
240            throw new ServletException("error initializing sru server", e);
241        } catch (InvocationTargetException e) {
242            throw new ServletException("error initializing sru server", e);
243        }
244
245        /*
246         * finally initialize the SRU server ...
247         */
248        try {
249            searchEngine.init(ctx, sruServerConfig, params);
250            sruServer = new SRUServer(sruServerConfig, searchEngine);
251        } catch (SRUConfigException e) {
252            throw new ServletException("error initializing sru server", e);
253        } catch (SRUException e) {
254            throw new ServletException("error initializing sru server", e);
255        }
256    }
257
258
259    /**
260     * Destroy the SRU server Servlet.
261     *
262     * @see javax.servlet.GenericServlet#destroy()
263     */
264    @Override
265    public void destroy() {
266        if (searchEngine != null) {
267            searchEngine.destroy();
268        }
269        super.destroy();
270    }
271
272
273    /**
274     * Handle a HTTP get request.
275     *
276     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
277     *      javax.servlet.http.HttpServletResponse)
278     */
279    @Override
280    protected void doGet(HttpServletRequest request,
281            HttpServletResponse response) throws ServletException, IOException {
282        if (sruServer == null) {
283            throw new ServletException("servlet is not properly initialized");
284        }
285        sruServer.handleRequest(request, response);
286    }
287
288
289    /**
290     * Handle a HTTP post request.
291     *
292     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest,
293     *      javax.servlet.http.HttpServletResponse)
294     */
295    @Override
296    protected void doPost(HttpServletRequest request,
297            HttpServletResponse response) throws ServletException, IOException {
298        if (sruServer == null) {
299            throw new ServletException("servlet is not properly initalized");
300        }
301        sruServer.handleRequest(request, response);
302    }
303
304
305    private void setDefaultConfigParam(Map<String, String> params, String key,
306            String value) {
307        if (!params.containsKey(key)) {
308            params.put(key, value);
309            log("NOTE: using default '" + value + "' for parameter '" + key +
310                    "', because it was not defined in context configuration.");
311            log("THIS IS NOT RECOMMENDED FOR PRODUCTION DEPLOYMENT!");
312        }
313    }
314
315} // class SRUServerServlet
Note: See TracBrowser for help on using the repository browser.