source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryServlet.java@ 24753

Last change on this file since 24753 was 24753, checked in by sjm84, 13 years ago

Some modifications to LibraryServlet to allow CGI formatted POST requests to go through the doGet method, also some initial code for handling file uploads

  • Property svn:keywords set to Author Date Id Revision
File size: 26.6 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.greenstone.util.GlobalProperties;
8import org.w3c.dom.Document;
9import org.w3c.dom.Element;
10import org.w3c.dom.Node;
11import org.w3c.dom.NodeList;
12import java.io.*;
13import javax.servlet.*;
14import javax.servlet.http.*;
15import java.util.Enumeration;
16import java.util.ArrayList;
17import java.util.HashMap;
18import java.util.Iterator;
19import java.util.List;
20import java.util.Map;
21import java.util.Set;
22import java.io.File;
23import java.lang.reflect.Type;
24import java.util.Hashtable;
25import org.apache.log4j.*;
26
27import com.google.gson.Gson;
28import com.google.gson.reflect.TypeToken;
29
30// Apache Commons
31import org.apache.commons.fileupload.FileItem;
32import org.apache.commons.fileupload.disk.DiskFileItemFactory;
33import org.apache.commons.fileupload.servlet.ServletFileUpload;
34import org.apache.commons.lang3.*;
35
36/**
37 * a servlet to serve the greenstone library - we are using servlets instead of
38 * cgi the init method is called only once - the first time the servlet classes
39 * are loaded. Each time a request comes in to the servlet, the session() method
40 * is called in a new thread (calls doGet/doPut etc) takes the a=p&p=home type
41 * args and builds a simple request to send to its receptionist, which returns a
42 * result in html, cos output=html is set in the request
43 *
44 * 18/Jul/07 xiao modify to make the cached parameters collection-specific. Most
45 * of the work is done in doGet(), except adding an inner class
46 * UserSessionCache.
47 *
48 * @see Receptionist
49 */
50public class LibraryServlet extends HttpServlet
51{
52
53 /** the receptionist to send messages to */
54 protected Receptionist recept = null;
55
56 /**
57 * the default language - is specified by setting a servlet param, otherwise
58 * DEFAULT_LANG is used
59 */
60 protected String default_lang = null;
61
62 /** Whether or not client-side XSLT support should be exposed */
63 protected boolean supports_client_xslt = false;
64
65 /**
66 * The default default - used if a default lang is not specified in the
67 * servlet params
68 */
69 protected final String DEFAULT_LANG = "en";
70
71 /** container Document to create XML Nodes */
72 protected Document doc = null;
73
74 /** a converter class to parse XML and create Docs */
75 protected XMLConverter converter = null;
76
77 /**
78 * the cgi stuff - the Receptionist can add new args to this
79 *
80 * its used by the servlet to determine what args to save
81 */
82 protected GSParams params = null;
83
84 /**
85 * user id - new one per session. This doesn't work if session state is
86 * saved between restarts - this requires this value to be saved too.
87 */
88 protected int next_user_id = 0;
89
90 /**
91 * a hash that contains all the active session IDs mapped to the cached
92 * items It is updated whenever the whole site or a particular collection is
93 * reconfigured using the command a=s&sa=c or a=s&sa=c&c=xxx It is in the
94 * form: sid -> (UserSessionCache object)
95 */
96 protected Hashtable session_ids_table = new Hashtable();
97
98 /**
99 * the maximum interval that the cached info remains in session_ids_table
100 * (in seconds) This is set in web.xml
101 */
102 protected int session_expiration = 1800;
103
104 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.LibraryServlet.class.getName());
105
106 /** initialise the servlet */
107 public void init(ServletConfig config) throws ServletException
108 {
109 // always call super.init;
110 super.init(config);
111 // disable preferences - does this work anyway??
112 //System.setProperty("java.util.prefs.PreferencesFactory", "org.greenstone.gsdl3.util.DisabledPreferencesFactory");
113
114 String library_name = config.getInitParameter(GSConstants.LIBRARY_NAME);
115 String gsdl3_home = config.getInitParameter(GSConstants.GSDL3_HOME);
116 String interface_name = config.getInitParameter(GSConstants.INTERFACE_NAME);
117
118 String allowXslt = (String) config.getInitParameter(GSConstants.ALLOW_CLIENT_SIDE_XSLT);
119 supports_client_xslt = allowXslt != null && allowXslt.equals("true");
120
121 this.default_lang = config.getInitParameter(GSConstants.DEFAULT_LANG);
122 String sess_expire = config.getInitParameter(GSXML.SESSION_EXPIRATION);
123
124 if (sess_expire != null && !sess_expire.equals(""))
125 {
126 this.session_expiration = Integer.parseInt(sess_expire);
127 }
128
129 if (library_name == null || interface_name == null)
130 {
131 // must have this
132 System.err.println("initialisation parameters not all set!");
133 System.err.println(" you must have libraryname and interfacename");
134 System.exit(1);
135 }
136
137 String site_name = config.getInitParameter(GSConstants.SITE_NAME);
138 String remote_site_name = null;
139 String remote_site_type = null;
140 String remote_site_address = null;
141
142 if (site_name == null)
143 {
144 // no site, try for communicator
145 remote_site_name = config.getInitParameter("remote_site_name");
146 remote_site_type = config.getInitParameter("remote_site_type");
147 remote_site_address = config.getInitParameter("remote_site_address");
148 if (remote_site_name == null || remote_site_type == null || remote_site_address == null)
149 {
150 System.err.println("initialisation paramters not all set!");
151 System.err.println("if site_name is not set, then you must have remote_site_name, remote_site_type and remote_site_address set");
152 System.exit(1);
153 }
154 }
155
156 if (this.default_lang == null)
157 {
158 // choose english
159 this.default_lang = DEFAULT_LANG;
160 }
161
162 HashMap config_params = new HashMap();
163
164 config_params.put(GSConstants.LIBRARY_NAME, library_name);
165 config_params.put(GSConstants.INTERFACE_NAME, interface_name);
166 config_params.put(GSConstants.ALLOW_CLIENT_SIDE_XSLT, supports_client_xslt);
167
168 if (site_name != null)
169 {
170 config_params.put(GSConstants.SITE_NAME, site_name);
171 }
172 this.converter = new XMLConverter();
173 this.doc = this.converter.newDOM();
174
175 // the receptionist -the servlet will talk to this
176 String recept_name = (String) config.getInitParameter("receptionist_class");
177 if (recept_name == null)
178 {
179 this.recept = new DefaultReceptionist();
180 }
181 else
182 {
183 try
184 {
185 this.recept = (Receptionist) Class.forName("org.greenstone.gsdl3.core." + recept_name).newInstance();
186 }
187 catch (Exception e)
188 { // cant use this new one, so use normal one
189 System.err.println("LibraryServlet configure exception when trying to use a new Receptionist " + recept_name + ": " + e.getMessage());
190 e.printStackTrace();
191 this.recept = new DefaultReceptionist();
192 }
193 }
194 this.recept.setConfigParams(config_params);
195
196 // 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.
197 if (site_name != null)
198 {
199 String mr_name = (String) config.getInitParameter("messagerouter_class");
200 MessageRouter message_router = null;
201 if (mr_name == null)
202 { // just use the normal MR
203 message_router = new MessageRouter();
204 }
205 else
206 { // try the specified one
207 try
208 {
209 message_router = (MessageRouter) Class.forName("org.greenstone.gsdl3.core." + mr_name).newInstance();
210 }
211 catch (Exception e)
212 { // cant use this new one, so use normal one
213 System.err.println("LibraryServlet configure exception when trying to use a new MessageRouter " + mr_name + ": " + e.getMessage());
214 e.printStackTrace();
215 message_router = new MessageRouter();
216 }
217 }
218
219 message_router.setSiteName(site_name);
220 message_router.setLibraryName(library_name);
221 message_router.configure();
222 this.recept.setMessageRouter(message_router);
223 }
224 else
225 {
226 // talking to a remote site, create a communicator
227 Communicator communicator = null;
228 // we need to create the XML to configure the communicator
229 Element site_elem = this.doc.createElement(GSXML.SITE_ELEM);
230 site_elem.setAttribute(GSXML.TYPE_ATT, remote_site_type);
231 site_elem.setAttribute(GSXML.NAME_ATT, remote_site_name);
232 site_elem.setAttribute(GSXML.ADDRESS_ATT, remote_site_address);
233
234 if (remote_site_type.equals(GSXML.COMM_TYPE_SOAP_JAVA))
235 {
236 communicator = new SOAPCommunicator();
237 }
238 else
239 {
240 System.err.println("LibraryServlet.init Error: invalid Communicator type: " + remote_site_type);
241 System.exit(1);
242 }
243
244 if (!communicator.configure(site_elem))
245 {
246 System.err.println("LibraryServlet.init Error: Couldn't configure communicator");
247 System.exit(1);
248 }
249 this.recept.setMessageRouter(communicator);
250 }
251
252 // the params arg thingy
253
254 String params_name = (String) config.getInitParameter("params_class");
255 if (params_name == null)
256 {
257 this.params = new GSParams();
258 }
259 else
260 {
261 try
262 {
263 this.params = (GSParams) Class.forName("org.greenstone.gsdl3.util." + params_name).newInstance();
264 }
265 catch (Exception e)
266 {
267 System.err.println("LibraryServlet configure exception when trying to use a new params thing " + params_name + ": " + e.getMessage());
268 e.printStackTrace();
269 this.params = new GSParams();
270 }
271 }
272 // pass it to the receptionist
273 this.recept.setParams(this.params);
274 this.recept.configure();
275
276 }
277
278 private void logUsageInfo(HttpServletRequest request)
279 {
280 String usageInfo = "";
281
282 //session-info: get params stored in the session
283 HttpSession session = request.getSession(true);
284 Enumeration attributeNames = session.getAttributeNames();
285 while (attributeNames.hasMoreElements())
286 {
287 String name = (String) attributeNames.nextElement();
288 usageInfo += name + "=" + session.getAttribute(name) + " ";
289 }
290
291 //logged info = general-info + session-info
292 usageInfo = request.getServletPath() + " " + //serlvet
293 "[" + request.getQueryString() + "]" + " " + //the query string
294 "[" + usageInfo.trim() + "]" + " " + // params stored in a session
295 request.getRemoteAddr() + " " + //remote address
296 request.getRequestedSessionId() + " " + //session id
297 request.getHeader("user-agent") + " "; //the remote brower info
298
299 logger.info(usageInfo);
300
301 }
302
303 public class UserSessionCache implements HttpSessionBindingListener
304 {
305
306 String session_id = "";
307
308 /**
309 * a hash that maps the session ID to a hashtable that maps the
310 * coll_name to its parameters coll_name -> Hashtable (param_name ->
311 * param_value)
312 */
313 protected Hashtable coll_name_params_table = null;
314
315 public UserSessionCache(String id, Hashtable table)
316 {
317 session_id = id;
318 coll_name_params_table = (table == null) ? new Hashtable() : table;
319 }
320
321 protected void cleanupCache(String coll_name)
322 {
323 if (coll_name_params_table.containsKey(coll_name))
324 {
325 coll_name_params_table.remove(coll_name);
326 }
327 }
328
329 protected Hashtable getParamsTable()
330 {
331 return coll_name_params_table;
332 }
333
334 public void valueBound(HttpSessionBindingEvent event)
335 {
336 // Do nothing
337 }
338
339 public void valueUnbound(HttpSessionBindingEvent event)
340 {
341 if (session_ids_table.containsKey(session_id))
342 {
343 session_ids_table.remove(session_id);
344 }
345 }
346
347 public int tableSize()
348 {
349 return (coll_name_params_table == null) ? 0 : coll_name_params_table.size();
350 }
351
352 }
353
354 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
355 {
356 logUsageInfo(request);
357
358 String query_string;
359 if(request.getMethod().equals("GET"))
360 {
361 query_string = request.getQueryString();
362 }
363 else if(request.getMethod().equals("POST"))
364 {
365 query_string = "";
366 Map paramMap = request.getParameterMap();
367 Iterator keyIter = paramMap.keySet().iterator();
368
369 while(keyIter.hasNext())
370 {
371 String current = (String)keyIter.next();
372 query_string += current + "=" + ((String[])paramMap.get(current))[0];
373 if(keyIter.hasNext())
374 {
375 query_string += "&";
376 }
377 }
378
379 DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
380
381 int sizeLimit = System.getProperties().containsKey("servlet.upload.filesize.limit") ? Integer.parseInt(System.getProperty("servlet.upload.filesize.limit")) : 20 * 1024 * 1024;
382
383 fileItemFactory.setSizeThreshold(sizeLimit);
384 fileItemFactory.setRepository(new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp"));
385
386 ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
387
388 try
389 {
390 List items = uploadHandler.parseRequest(request);
391 Iterator iter = items.iterator();
392 while(iter.hasNext())
393 {
394 FileItem current = (FileItem) iter.next();
395 if(current.isFormField())
396 {
397 query_string += current.getFieldName() + "=" + current.getString();
398 if(iter.hasNext())
399 {
400 query_string += "&";
401 }
402 }
403 else
404 {
405 File file = new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp" + File.separator + current.getName());
406 current.write(file);
407 }
408 }
409 }
410 catch (Exception e)
411 {
412 logger.error("Exception in LibraryServlet -> " + e.getMessage());
413 }
414
415 if(query_string.equals(""))
416 {
417 query_string = null;
418 }
419 }
420 else
421 {
422 query_string = null;
423 }
424
425 if (query_string != null)
426 {
427 String[] query_arr = StringUtils.split(query_string, "&");
428 boolean redirect = false;
429 String href = null;
430 String rl = null;
431 String[] nameval = new String[2]; // Reuse it for memory efficiency purposes
432
433 for (int i = 0; i < query_arr.length; i++)
434 {
435 if (query_arr[i].startsWith("el="))
436 {
437 if (query_arr[i].substring(query_arr[i].indexOf("=") + 1, query_arr[i].length()).equals("direct"))
438 {
439 redirect = true;
440 }
441 }
442 else if (query_arr[i].startsWith("href="))
443 {
444 href = query_arr[i].substring(query_arr[i].indexOf("=") + 1, query_arr[i].length());
445 href = StringUtils.replace(href, "%2f", "/");
446 href = StringUtils.replace(href, "%7e", "~");
447 href = StringUtils.replace(href, "%3f", "?");
448 href = StringUtils.replace(href, "%3A", "\\:");
449 }
450 else if (query_arr[i].startsWith("rl="))
451 {
452 rl = query_arr[i].substring(query_arr[i].indexOf("=") + 1, query_arr[i].length());
453 }
454 }
455
456 //if query_string contains "el=", the web page will be redirected to the external URl, otherwise a greenstone page with an external URL will be displayed
457 //"rl=0" this is an external link
458 //"rl=1" this is an internal link
459 if ((redirect) && (href != null) && (rl.equals("0")))
460 {// This is an external link, the web page is re-directed to the external URL (&el=&rl=0&href="http://...")
461 response.setContentType("text/xml");
462 response.sendRedirect(href);
463 }
464 }
465
466 // Nested Diagnostic Configurator to identify the client for
467 HttpSession session = request.getSession(true);
468 session.setMaxInactiveInterval(session_expiration);
469 String uid = (String) session.getAttribute(GSXML.USER_ID_ATT);
470 if (uid == null)
471 {
472 uid = "" + getNextUserId();
473 session.setAttribute(GSXML.USER_ID_ATT, uid);
474 }
475 request.setCharacterEncoding("UTF-8");
476 response.setContentType("text/html;charset=UTF-8");
477 PrintWriter out = response.getWriter();
478
479 String lang = request.getParameter(GSParams.LANGUAGE);
480 if (lang == null || lang.equals(""))
481 {
482 // try the session cached lang
483 lang = (String) session.getAttribute(GSParams.LANGUAGE);
484 if (lang == null || lang.equals(""))
485 {
486 // still not set, use the default
487 lang = this.default_lang;
488 }
489 }
490
491 // set the lang in the session
492 session.setAttribute(GSParams.LANGUAGE, lang);
493
494 String output = request.getParameter(GSParams.OUTPUT);
495 if (output == null || output.equals(""))
496 {
497 output = "html"; // uses html by default
498 }
499
500 // If server output, force a switch to traditional interface
501 //output = (output.equals("server")) ? "html" : output;
502
503 // Force change the output mode if client-side XSLT is supported - server vs. client
504 // BUT only if the library allows client-side transforms
505 if (supports_client_xslt)
506 {
507 // MUST be done before the xml_message is built
508 Cookie[] cookies = request.getCookies();
509 Cookie xsltCookie = null;
510
511 // The client has cookies enabled and a value set - use it!
512 if (cookies != null)
513 {
514 for (Cookie c : cookies)
515 {
516 if (c.getName().equals("supportsXSLT"))
517 {
518 xsltCookie = c;
519 break;
520 }
521 }
522 output = (xsltCookie != null && xsltCookie.getValue().equals("true") && output.equals("html")) ? "xsltclient" : output;
523 }
524 }
525
526 // the request to the receptionist
527 Element xml_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
528 Element xml_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", lang, uid);
529 xml_request.setAttribute(GSXML.OUTPUT_ATT, output);
530
531 xml_message.appendChild(xml_request);
532
533 String action = request.getParameter(GSParams.ACTION);
534 String subaction = request.getParameter(GSParams.SUBACTION);
535 String collection = request.getParameter(GSParams.COLLECTION);
536 String service = request.getParameter(GSParams.SERVICE);
537
538 // We clean up the cache session_ids_table if system
539 // commands are issued (and also don't need to do caching for this request)
540 boolean should_cache = true;
541 if (action != null && action.equals(GSParams.SYSTEM))
542 {
543 should_cache = false;
544
545 // we may want to remove all collection cache info, or just a specific collection
546 boolean clean_all = true;
547 String clean_collection = null;
548 // system commands are to activate/deactivate stuff
549 // collection param is in the sc parameter.
550 // don't like the fact that it is hard coded here
551 String coll = request.getParameter(GSParams.SYSTEM_CLUSTER);
552 if (coll != null && !coll.equals(""))
553 {
554 clean_all = false;
555 clean_collection = coll;
556 }
557 else
558 {
559 // check other system types
560 if (subaction.equals("a") || subaction.equals("d"))
561 {
562 String module_name = request.getParameter("sn");
563 if (module_name != null && !module_name.equals(""))
564 {
565 clean_all = false;
566 clean_collection = module_name;
567 }
568 }
569 }
570 if (clean_all)
571 {
572 session_ids_table = new Hashtable();
573 session.removeAttribute(GSXML.USER_SESSION_CACHE_ATT);
574 }
575 else
576 {
577 // just clean up info for clean_collection
578 ArrayList cache_list = new ArrayList(session_ids_table.values());
579 for (int i = 0; i < cache_list.size(); i++)
580 {
581 UserSessionCache cache = (UserSessionCache) cache_list.get(i);
582 cache.cleanupCache(clean_collection);
583 }
584
585 }
586
587 }
588
589 // cache_key is the collection name, or service name
590 String cache_key = collection;
591 if (cache_key == null || cache_key.equals(""))
592 {
593 cache_key = service;
594 }
595
596 // logger.info("should_cache= " + should_cache);
597
598 //clear the collection-specific cache in the session, since we have no way to know whether this session is
599 //about the same collection as the last session or not.
600 Enumeration attributeNames = session.getAttributeNames();
601 while (attributeNames.hasMoreElements())
602 {
603 String name = (String) attributeNames.nextElement();
604 if (!name.equals(GSXML.USER_SESSION_CACHE_ATT) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT))
605 {
606
607 session.removeAttribute(name);
608 }
609 }
610
611 UserSessionCache session_cache = null;
612 Hashtable param_table = null;
613 Hashtable table = null;
614 String sid = session.getId();
615 if (should_cache == true && cache_key != null && !cache_key.equals(""))
616 {
617 if (session_ids_table.containsKey(sid))
618 {
619 session_cache = (UserSessionCache) session_ids_table.get(sid);
620 param_table = session_cache.getParamsTable();
621 logger.info("collections in table: " + tableToString(param_table));
622 if (param_table.containsKey(cache_key))
623 {
624 //logger.info("existing table: " + collection);
625 table = (Hashtable) param_table.get(cache_key);
626 }
627 else
628 {
629 table = new Hashtable();
630 param_table.put(cache_key, table);
631 //logger.info("new table: " + collection);
632 }
633 }
634 else
635 {
636 param_table = new Hashtable();
637 table = new Hashtable();
638 param_table.put(cache_key, table);
639 session_cache = new UserSessionCache(sid, param_table);
640 session_ids_table.put(sid, session_cache);
641 session.setAttribute(GSXML.USER_SESSION_CACHE_ATT, session_cache);
642 //logger.info("new session id");
643 }
644 }
645
646 if (action == null || action.equals(""))
647 {
648 // should we do all the following stuff if using default page?
649 // display the home page - the default page
650 xml_request.setAttribute(GSXML.ACTION_ATT, "p");
651 xml_request.setAttribute(GSXML.SUBACTION_ATT, PageAction.HOME_PAGE);
652 }
653 else
654 {
655 xml_request.setAttribute(GSXML.ACTION_ATT, action);
656 if (subaction != null)
657 {
658 xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction);
659 }
660
661 // create the param list for the greenstone request - includes
662 // the params from the current request and any others from the saved session
663 Element xml_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
664 xml_request.appendChild(xml_param_list);
665
666 Enumeration params = request.getParameterNames();
667 while (params.hasMoreElements())
668 {
669 String name = (String) params.nextElement();
670 if (!name.equals(GSParams.ACTION) && !name.equals(GSParams.SUBACTION) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSParams.OUTPUT))
671 {// we have already dealt with these
672
673 String value = "";
674 String[] values = request.getParameterValues(name);
675 value = values[0];
676 if (values.length > 1)
677 {
678 for (int i = 1; i < values.length; i++)
679 {
680 value += "," + values[i];
681 }
682 }
683 // either add it to the param list straight away, or save it to the session and add it later
684 if (this.params.shouldSave(name) && table != null)
685 {
686 table.put(name, value);
687 }
688 else
689 {
690 Element param = this.doc.createElement(GSXML.PARAM_ELEM);
691 param.setAttribute(GSXML.NAME_ATT, name);
692 param.setAttribute(GSXML.VALUE_ATT, GSXML.xmlSafe(value));
693 xml_param_list.appendChild(param);
694 }
695 }
696 }
697 //put everything in the table into the session
698 // do we need to do this? why not just put from table into param list
699 if (table != null)
700 {
701 Enumeration keys = table.keys();
702 while (keys.hasMoreElements())
703 {
704 String name = (String) keys.nextElement();
705 session.setAttribute(name, (String) table.get(name));
706 }
707 }
708
709 // put in all the params from the session cache
710 params = session.getAttributeNames();
711 while (params.hasMoreElements())
712 {
713 String name = (String) params.nextElement();
714
715 if (!name.equals(GSXML.USER_SESSION_CACHE_ATT) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT))
716 {
717
718 // lang and uid are stored but we dont want it in the param list cos its already in the request
719 Element param = this.doc.createElement(GSXML.PARAM_ELEM);
720 param.setAttribute(GSXML.NAME_ATT, name);
721 String value = GSXML.xmlSafe((String) session.getAttribute(name));
722
723 // ugly hack to undo : escaping
724 value = StringUtils.replace(value, "%3A", "\\:");
725 param.setAttribute(GSXML.VALUE_ATT, value);
726 xml_param_list.appendChild(param);
727 }
728 }
729 }
730
731 if (!output.equals("html") && !output.equals("server") && !output.equals("xsltclient"))
732 {
733 response.setContentType("text/xml"); // for now use text
734 }
735
736 //Add custom HTTP headers if requested
737 String httpHeadersParam = request.getParameter(GSParams.HTTPHEADERFIELDS);
738 if (httpHeadersParam != null && httpHeadersParam.length() > 0)
739 {
740 Gson gson = new Gson();
741 Type type = new TypeToken<List<Map<String, String>>>()
742 {
743 }.getType();
744 List<Map<String, String>> httpHeaders = gson.fromJson(httpHeadersParam, type);
745 if (httpHeaders != null && httpHeaders.size() > 0)
746 {
747
748 for (int j = 0; j < httpHeaders.size(); j++)
749 {
750 Map nameValueMap = (Map) httpHeaders.get(j);
751 String name = (String) nameValueMap.get("name");
752 String value = (String) nameValueMap.get("value");
753
754 if (name != null && value != null)
755 {
756 response.setHeader(name, value);
757 }
758 }
759 }
760 }
761
762 Node xml_result = this.recept.process(xml_message);
763 encodeURLs(xml_result, response);
764 out.println(this.converter.getPrettyString(xml_result));
765
766 displaySize(session_ids_table);
767
768 } //end of doGet(HttpServletRequest, HttpServletResponse)
769
770 //a debugging method
771 private void displaySize(Hashtable table)
772 {
773 if (table == null)
774 {
775 logger.info("cached table is null");
776 return;
777 }
778 if (table.size() == 0)
779 {
780 logger.info("cached table size is zero");
781 return;
782 }
783 int num_cached_coll = 0;
784 ArrayList cache_list = new ArrayList(table.values());
785 for (int i = 0; i < cache_list.size(); i++)
786 {
787 num_cached_coll += ((UserSessionCache) cache_list.get(i)).tableSize();
788 }
789 logger.info("Number of sessions : total number of cached collection info = " + table.size() + " : " + num_cached_coll);
790 }
791
792 /** merely a debugging method! */
793 private String tableToString(Hashtable table)
794 {
795 String str = "";
796 Enumeration keys = table.keys();
797 while (keys.hasMoreElements())
798 {
799 String name = (String) keys.nextElement();
800 str += name + ", ";
801 }
802 return str;
803 }
804
805 /**
806 * this goes through each URL and adds in a session id if needed-- its
807 * needed if the browser doesn't accept cookies also escapes things if
808 * needed
809 */
810 protected void encodeURLs(Node dataNode, HttpServletResponse response)
811 {
812
813 if (dataNode == null)
814 {
815 return;
816 }
817
818 Element data = null;
819
820 short nodeType = dataNode.getNodeType();
821 if (nodeType == Node.DOCUMENT_NODE)
822 {
823 Document docNode = (Document) dataNode;
824 data = docNode.getDocumentElement();
825 }
826 else
827 {
828 data = (Element) dataNode;
829 }
830
831 if (data != null)
832 {
833
834 // get all the <a> elements
835 NodeList hrefs = data.getElementsByTagName("a");
836 // Instead of calculating each iteration...
837 int hrefscount = hrefs.getLength();
838
839 for (int i = 0; hrefs != null && i < hrefscount; i++)
840 {
841 Element a = (Element) hrefs.item(i);
842 // ugly hack to get rid of : in the args - interferes with session handling
843 String href = a.getAttribute("href");
844 if (!href.equals(""))
845 {
846 if (href.indexOf("?") != -1)
847 {
848 String[] parts = StringUtils.split(href, "\\?", -1);
849 if (parts.length == 1)
850 {
851 parts[0] = StringUtils.replace(parts[0], ":", "%3A");
852 href = "?" + parts[0];
853 }
854 else
855 {
856 parts[1] = StringUtils.replace(parts[1], ":", "%3A");
857 href = parts[0] + "?" + parts[1];
858 }
859
860 }
861 a.setAttribute("href", response.encodeURL(href));
862 }
863 }
864
865 // now find any submit bits - get all the <form> elements
866 NodeList forms = data.getElementsByTagName("form");
867 int formscount = forms.getLength();
868 for (int i = 0; forms != null && i < formscount; i++)
869 {
870 Element form = (Element) forms.item(i);
871 form.setAttribute("action", response.encodeURL(form.getAttribute("action")));
872 }
873 // are these the only cases where URLs occur??
874 // we should only do this for greenstone urls?
875 }
876
877 }
878
879 synchronized protected int getNextUserId()
880 {
881 next_user_id++;
882 return next_user_id;
883 }
884
885 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
886 {
887 doGet(request, response);
888 }
889}
Note: See TracBrowser for help on using the repository browser.