source: trunk/gsdl3/src/java/org/greenstone/gsdl3/LibraryServlet.java@ 13273

Last change on this file since 13273 was 13273, checked in by shaoqun, 17 years ago

replace Category class which is deprecated with Logger class

  • Property svn:keywords set to Author Date Id Revision
File size: 13.8 KB
Line 
1package org.greenstone.gsdl3;
2
3import org.greenstone.gsdl3.comms.*;
4import org.greenstone.gsdl3.core.*;
5import org.greenstone.gsdl3.util.*;
6import org.greenstone.gsdl3.action.PageAction; // used to get the default action
7import org.w3c.dom.Document;
8import org.w3c.dom.Element;
9import org.w3c.dom.NodeList;
10import java.io.*;
11import javax.servlet.*;
12import javax.servlet.http.*;
13import java.util.Enumeration;
14import java.util.HashMap;
15import java.io.File;
16
17import org.apache.log4j.*;
18
19/** a servlet to serve the greenstone library - we are using servlets instead
20 * of cgi
21 * the init method is called only once - the first time the servlet classes
22 * are loaded. Each time a request comes in to the servlet, the session()
23 * method is called in a new thread (calls doGet/doPut etc)
24 * takes the a=p&p=home type args and builds a simple request to send to
25 * its receptionist, which returns a result in html, cos output=html
26 * is set in the request
27 * @see Receptionist
28 */
29public class LibraryServlet extends HttpServlet {
30
31 /** the receptionist to send messages to */
32 protected Receptionist recept=null;
33 /** the default language - is specified by setting a servlet param,
34 * otherwise DEFAULT_LANG is used*/
35 protected String default_lang= null;
36 /** The default default - used if a default lang is not specified
37 * in the servlet params */
38 protected final String DEFAULT_LANG = "en";
39 /** container Document to create XML Nodes */
40 protected Document doc=null;
41 /** a converter class to parse XML and create Docs */
42 protected XMLConverter converter=null;
43 /** the cgi stuff - the Receptionist can add new args to this
44 * its used by the servlet to determine what args to save */
45 protected GSParams params = null;
46
47 /** user id - new one per session. This doesn't work if session state is saved between restarts - this requires this value to be saved too. */
48 protected int next_user_id = 0;
49
50 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.LibraryServlet.class.getName());
51
52 /** initialise the servlet
53 */
54 public void init(ServletConfig config) throws ServletException {
55 // always call super.init;
56 super.init(config);
57 // disable preferences - does this work anyway??
58 //System.setProperty("java.util.prefs.PreferencesFactory", "org.greenstone.gsdl3.util.DisabledPreferencesFactory");
59
60
61 String library_name = config.getInitParameter(GSConstants.LIBRARY_NAME);
62 String gsdl3_home = config.getInitParameter(GSConstants.GSDL3_HOME);
63 String interface_name = config.getInitParameter(GSConstants.INTERFACE_NAME);
64 this.default_lang = config.getInitParameter(GSConstants.DEFAULT_LANG);
65
66 if (library_name == null || interface_name ==null) {
67 // must have this
68 System.err.println("initialisation parameters not all set!");
69 System.err.println(" you must have libraryname and interfacename");
70 System.exit(1);
71 }
72
73 String site_name = config.getInitParameter(GSConstants.SITE_NAME);
74 String remote_site_name = null;
75 String remote_site_type = null;
76 String remote_site_address = null;
77
78 if (site_name == null) {
79 // no site, try for communicator
80 remote_site_name = config.getInitParameter("remote_site_name");
81 remote_site_type = config.getInitParameter("remote_site_type");
82 remote_site_address = config.getInitParameter("remote_site_address");
83 if (remote_site_name == null || remote_site_type == null || remote_site_address == null) {
84 System.err.println("initialisation paramters not all set!");
85 System.err.println("if site_name is not set, then you must have remote_site_name, remote_site_type and remote_site_address set");
86 System.exit(1);
87 }
88 }
89
90 if (this.default_lang == null) {
91 // choose english
92 this.default_lang = DEFAULT_LANG;
93 }
94
95 HashMap config_params = new HashMap();
96
97 config_params.put(GSConstants.LIBRARY_NAME, library_name);
98 config_params.put(GSConstants.INTERFACE_NAME, interface_name);
99 if (site_name != null) {
100 config_params.put(GSConstants.SITE_NAME, site_name);
101 }
102 this.converter = new XMLConverter();
103 this.doc = this.converter.newDOM();
104
105 // the receptionist -the servlet will talk to this
106 String recept_name = (String)config.getInitParameter("receptionist_class");
107 if (recept_name == null) {
108 this.recept = new DefaultReceptionist();
109 } else {
110 try {
111 this.recept = (Receptionist)Class.forName("org.greenstone.gsdl3.core."+recept_name).newInstance();
112 } catch (Exception e) { // cant use this new one, so use normal one
113 System.err.println("LibraryServlet configure exception when trying to use a new Receptionist "+recept_name+": "+e.getMessage());
114 e.printStackTrace();
115 this.recept = new DefaultReceptionist();
116 }
117 }
118 this.recept.setConfigParams(config_params);
119
120 // the receptionist uses a MessageRouter or Communicator to send its requests to. We either create a MessageRouter here for the designated site (if site_name set), or we create a Communicator for a remote site. The is given to teh Receptionist, and the servlet never talks to it again.directly.
121 if (site_name != null) {
122 String mr_name = (String)config.getInitParameter("messagerouter_class");
123 MessageRouter message_router = null;
124 if (mr_name == null) { // just use the normal MR
125 message_router = new MessageRouter();
126 } else { // try the specified one
127 try {
128 message_router = (MessageRouter)Class.forName("org.greenstone.gsdl3.core."+mr_name).newInstance();
129 } catch (Exception e) { // cant use this new one, so use normal one
130 System.err.println("LibraryServlet configure exception when trying to use a new MessageRouter "+mr_name+": "+e.getMessage());
131 e.printStackTrace();
132 message_router = new MessageRouter();
133 }
134 }
135
136 message_router.setSiteName(site_name);
137 message_router.configure();
138 this.recept.setMessageRouter(message_router);
139 } else {
140 // talking to a remote site, create a communicator
141 Communicator communicator = null;
142 // we need to create the XML to configure the communicator
143 Element site_elem = this.doc.createElement(GSXML.SITE_ELEM);
144 site_elem.setAttribute(GSXML.TYPE_ATT, remote_site_type);
145 site_elem.setAttribute(GSXML.NAME_ATT, remote_site_name);
146 site_elem.setAttribute(GSXML.ADDRESS_ATT, remote_site_address);
147
148 if (remote_site_type.equals(GSXML.COMM_TYPE_SOAP_JAVA)) {
149 communicator = new SOAPCommunicator();
150 } else {
151 System.err.println("LibraryServlet.init Error: invalid Communicator type: "+remote_site_type);
152 System.exit(1);
153 }
154
155 if (!communicator.configure(site_elem)) {
156 System.err.println("LibraryServlet.init Error: Couldn't configure communicator");
157 System.exit(1);
158 }
159 this.recept.setMessageRouter(communicator);
160 }
161
162 // the params arg thingy
163
164 String params_name = (String)config.getInitParameter("params_class");
165 if (params_name == null) {
166 this.params = new GSParams();
167 } else {
168 try {
169 this.params = (GSParams)Class.forName("org.greenstone.gsdl3.util."+params_name).newInstance();
170 } catch (Exception e) {
171 System.err.println("LibraryServlet configure exception when trying to use a new params thing "+params_name+": "+e.getMessage());
172 e.printStackTrace();
173 this.params = new GSParams();
174 }
175 }
176 // pass it to the receptionist
177 this.recept.setParams(this.params);
178 this.recept.configure();
179
180 }
181
182
183 private void logUsageInfo(HttpServletRequest request){
184 String usageInfo = "";
185
186 //session-info: get params stored in the session
187 HttpSession session = request.getSession(true);
188 Enumeration attributeNames = session.getAttributeNames();
189 while(attributeNames.hasMoreElements()) {
190 String name = (String)attributeNames.nextElement();
191 usageInfo +=name+"="+session.getAttribute(name)+" ";
192 }
193
194 //logged info = general-info + session-info
195 usageInfo =
196 request.getServletPath()+" "+ //serlvet
197 "["+request.getQueryString()+"]" +" "+ //the query string
198 "["+usageInfo.trim()+"]" +" "+ // params stored in a session
199 request.getRemoteAddr()+" "+ //remote address
200 request.getRequestedSessionId()+" "+ //session id
201 request.getHeader("user-agent")+" "; //the remote brower info
202
203 logger.info(usageInfo);
204
205 }
206
207
208 public void doGet(HttpServletRequest request,
209 HttpServletResponse response)
210 throws ServletException, IOException {
211
212 logUsageInfo(request);
213
214 // Nested Diagnostic Configurator to identify the client for
215
216 HttpSession session = request.getSession(true);
217 String uid = (String)session.getAttribute(GSXML.USER_ID_ATT);
218 if (uid ==null) {
219 uid = ""+getNextUserId();
220 session.setAttribute(GSXML.USER_ID_ATT, uid);
221 }
222 request.setCharacterEncoding("UTF-8");
223 response.setContentType("text/html;charset=UTF-8");
224 PrintWriter out = response.getWriter();
225
226 String lang = request.getParameter(GSParams.LANGUAGE);
227 if (lang==null || lang.equals("")) {
228 // try the session cached lang
229 lang = (String)session.getAttribute(GSParams.LANGUAGE);
230 if (lang==null || lang.equals("")) {
231 // still not set, use the default
232 lang = this.default_lang;
233 }
234 }
235
236 // set the lang in the session
237 session.setAttribute(GSParams.LANGUAGE, lang);
238
239 String output = request.getParameter(GSParams.OUTPUT);
240 if (output==null || output.equals("")) {
241 output = "html"; // uses html by default
242 }
243
244 // the request to the receptionist
245 Element xml_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
246 Element xml_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", lang, uid);
247 xml_request.setAttribute(GSXML.OUTPUT_ATT, output);
248 xml_message.appendChild(xml_request);
249
250
251 String action = request.getParameter(GSParams.ACTION);
252 String subaction = request.getParameter(GSParams.SUBACTION);
253 if (action==null || action.equals("")) {
254 // should we do all the following stuff if using default page?
255 // display the home page - the default page
256 action = "p";
257 subaction = PageAction.HOME_PAGE;
258 xml_request.setAttribute(GSXML.ACTION_ATT, action);
259 xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction);
260
261 } else {
262
263 xml_request.setAttribute(GSXML.ACTION_ATT, action);
264 if (subaction != null) {
265 xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction);
266 }
267
268 // create the param list for the greenstone request - includes
269 // the params from the current request and any others from the saved session
270 Element xml_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
271 xml_request.appendChild(xml_param_list);
272
273 Enumeration params = request.getParameterNames();
274 while(params.hasMoreElements()) {
275 String name = (String)params.nextElement();
276 if (!name.equals(GSParams.ACTION) && !name.equals(GSParams.SUBACTION) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSParams.OUTPUT)) {// we have already dealt with these
277 String value="";
278 String [] values = request.getParameterValues(name);
279 value = values[0];
280 if (values.length > 1) {
281 for (int i=1; i< values.length; i++) {
282 value += ","+values[i];
283 }
284 }
285 // either add it to the param list straight away, or save it to the session and add it later
286 if (this.params.shouldSave(name)) {
287 session.setAttribute(name, value);
288 } else {
289 Element param = this.doc.createElement(GSXML.PARAM_ELEM);
290 param.setAttribute(GSXML.NAME_ATT, name);
291 param.setAttribute(GSXML.VALUE_ATT, GSXML.xmlSafe(value));
292 xml_param_list.appendChild(param);
293 }
294 }
295 }
296
297 // put in all the params from the session cache
298 params = session.getAttributeNames();
299 while(params.hasMoreElements()) {
300 String name = (String)params.nextElement();
301
302 if ( !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT)) { // lang and uid are stored but we dont want it in the param list cos its already in the request
303
304 Element param = this.doc.createElement(GSXML.PARAM_ELEM);
305 param.setAttribute(GSXML.NAME_ATT, name);
306 String value = GSXML.xmlSafe((String)session.getAttribute(name));
307 // ugly hack to undo : escaping
308 value = value.replaceAll("%3A", "\\:");
309 param.setAttribute(GSXML.VALUE_ATT,value);
310 xml_param_list.appendChild(param);
311 }
312 }
313
314
315 }
316
317 if (!output.equals("html")) {
318 response.setContentType("text/xml"); // for now use text
319 }
320
321 //GSXML.printXMLNode(xml_message);
322
323 Element xml_result = this.recept.process(xml_message);
324 encodeURLs(xml_result, response);
325 out.println(this.converter.getPrettyString(xml_result));
326 }
327
328 /** this goes through each URL and adds in a session id if needed--
329 * its needed if the browser doesn't accept cookies
330 * also escapes things if needed
331 */
332 protected void encodeURLs(Element data, HttpServletResponse response) {
333
334 if (data == null) {
335 return;
336 }
337 // get all the <a> elements
338 NodeList hrefs = data.getElementsByTagName("a");
339 for (int i=0; i<hrefs.getLength(); i++) {
340 Element a = (Element)hrefs.item(i);
341 // ugly hack to get rid of : in the args - interferes with session handling
342 String href = a.getAttribute("href");
343 if (!href.equals("")) {
344 if (href.indexOf("?")!=-1) {
345 String[] parts = href.split("\\?", -1);
346 parts[1]=parts[1].replaceAll(":", "%3A");
347 href = parts[0]+"?"+parts[1];
348 }
349 a.setAttribute("href", response.encodeURL(href));
350 }
351 }
352
353 // now find any submit bits - get all the <form> elements
354 NodeList forms = data.getElementsByTagName("form");
355 for (int i=0; i<forms.getLength(); i++) {
356 Element form = (Element)forms.item(i);
357 form.setAttribute("action", response.encodeURL(form.getAttribute("action")));
358 }
359 // are these the only cases where URLs occur??
360 // we should only do this for greenstone urls?
361
362 }
363
364 synchronized protected int getNextUserId() {
365 next_user_id++;
366 return next_user_id;
367 }
368
369 public void doPost(HttpServletRequest request,
370 HttpServletResponse response)
371 throws ServletException, IOException {
372 doGet(request,response);
373
374 }
375}
Note: See TracBrowser for help on using the repository browser.