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

Last change on this file since 24967 was 24967, checked in by sjm84, 12 years ago

Multiple files can now be specified using the fl parameter, separated by :

  • Property svn:keywords set to Author Date Id Revision
File size: 27.7 KB
RevLine 
[3309]1package org.greenstone.gsdl3;
2
[11023]3import org.greenstone.gsdl3.comms.*;
[3309]4import org.greenstone.gsdl3.core.*;
5import org.greenstone.gsdl3.util.*;
[3652]6import org.greenstone.gsdl3.action.PageAction; // used to get the default action
[24753]7import org.greenstone.util.GlobalProperties;
[3652]8import org.w3c.dom.Document;
9import org.w3c.dom.Element;
[16374]10import org.w3c.dom.Node;
[4259]11import org.w3c.dom.NodeList;
[3309]12import java.io.*;
13import javax.servlet.*;
14import javax.servlet.http.*;
[3346]15import java.util.Enumeration;
[14498]16import java.util.ArrayList;
[4690]17import java.util.HashMap;
[24753]18import java.util.Iterator;
[24052]19import java.util.List;
20import java.util.Map;
[24753]21import java.util.Set;
[3346]22import java.io.File;
[24052]23import java.lang.reflect.Type;
[14498]24import java.util.Hashtable;
[13122]25import org.apache.log4j.*;
26
[24052]27import com.google.gson.Gson;
28import com.google.gson.reflect.TypeToken;
29
[23790]30// Apache Commons
[24753]31import org.apache.commons.fileupload.FileItem;
32import org.apache.commons.fileupload.disk.DiskFileItemFactory;
33import org.apache.commons.fileupload.servlet.ServletFileUpload;
[23790]34import org.apache.commons.lang3.*;
[14498]35
[24753]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{
[18223]52
[24019]53 /** the receptionist to send messages to */
[24753]54 protected Receptionist recept = null;
[18223]55
[24753]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;
[18223]61
[24019]62 /** Whether or not client-side XSLT support should be exposed */
63 protected boolean supports_client_xslt = false;
[18223]64
[24753]65 /**
66 * The default default - used if a default lang is not specified in the
67 * servlet params
68 */
[24019]69 protected final String DEFAULT_LANG = "en";
[18223]70
[24019]71 /** container Document to create XML Nodes */
[24753]72 protected Document doc = null;
[14498]73
[24019]74 /** a converter class to parse XML and create Docs */
[24753]75 protected XMLConverter converter = null;
[6301]76
[24753]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 */
[24019]82 protected GSParams params = null;
[12021]83
[24753]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 */
[24019]88 protected int next_user_id = 0;
[18223]89
[24753]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 */
[24019]96 protected Hashtable session_ids_table = new Hashtable();
[18223]97
[24753]98 /**
99 * the maximum interval that the cached info remains in session_ids_table
100 * (in seconds) This is set in web.xml
101 */
[24019]102 protected int session_expiration = 1800;
[13122]103
[24019]104 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.LibraryServlet.class.getName());
[18223]105
[24753]106 /** initialise the servlet */
107 public void init(ServletConfig config) throws ServletException
108 {
[24019]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");
[24753]113
[24019]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);
[24753]117
118 String allowXslt = (String) config.getInitParameter(GSConstants.ALLOW_CLIENT_SIDE_XSLT);
[24019]119 supports_client_xslt = allowXslt != null && allowXslt.equals("true");
[24753]120
[24019]121 this.default_lang = config.getInitParameter(GSConstants.DEFAULT_LANG);
122 String sess_expire = config.getInitParameter(GSXML.SESSION_EXPIRATION);
[24753]123
124 if (sess_expire != null && !sess_expire.equals(""))
125 {
[24019]126 this.session_expiration = Integer.parseInt(sess_expire);
127 }
[24753]128
129 if (library_name == null || interface_name == null)
130 {
[24019]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 }
[24753]136
[24019]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;
[24753]141
142 if (site_name == null)
143 {
[24019]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");
[24753]148 if (remote_site_name == null || remote_site_type == null || remote_site_address == null)
149 {
[24019]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 }
[24753]155
156 if (this.default_lang == null)
157 {
[24019]158 // choose english
159 this.default_lang = DEFAULT_LANG;
160 }
[24753]161
[24019]162 HashMap config_params = new HashMap();
[24753]163
[24019]164 config_params.put(GSConstants.LIBRARY_NAME, library_name);
[24753]165 config_params.put(GSConstants.INTERFACE_NAME, interface_name);
[24019]166 config_params.put(GSConstants.ALLOW_CLIENT_SIDE_XSLT, supports_client_xslt);
[24753]167
168 if (site_name != null)
169 {
[24019]170 config_params.put(GSConstants.SITE_NAME, site_name);
171 }
172 this.converter = new XMLConverter();
173 this.doc = this.converter.newDOM();
[24753]174
[24019]175 // the receptionist -the servlet will talk to this
[24753]176 String recept_name = (String) config.getInitParameter("receptionist_class");
177 if (recept_name == null)
178 {
[24019]179 this.recept = new DefaultReceptionist();
[24753]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());
[24019]190 e.printStackTrace();
191 this.recept = new DefaultReceptionist();
192 }
193 }
194 this.recept.setConfigParams(config_params);
[24753]195
[24019]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.
[24753]197 if (site_name != null)
198 {
199 String mr_name = (String) config.getInitParameter("messagerouter_class");
[24019]200 MessageRouter message_router = null;
[24753]201 if (mr_name == null)
202 { // just use the normal MR
[24019]203 message_router = new MessageRouter();
[24753]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());
[24019]214 e.printStackTrace();
215 message_router = new MessageRouter();
216 }
217 }
[24753]218
[24019]219 message_router.setSiteName(site_name);
220 message_router.setLibraryName(library_name);
221 message_router.configure();
222 this.recept.setMessageRouter(message_router);
[24753]223 }
224 else
225 {
[24019]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);
[24753]233
234 if (remote_site_type.equals(GSXML.COMM_TYPE_SOAP_JAVA))
235 {
[24019]236 communicator = new SOAPCommunicator();
[24753]237 }
238 else
239 {
240 System.err.println("LibraryServlet.init Error: invalid Communicator type: " + remote_site_type);
[24019]241 System.exit(1);
242 }
[24753]243
244 if (!communicator.configure(site_elem))
245 {
[24019]246 System.err.println("LibraryServlet.init Error: Couldn't configure communicator");
247 System.exit(1);
248 }
249 this.recept.setMessageRouter(communicator);
250 }
[24753]251
[24019]252 // the params arg thingy
[24753]253
254 String params_name = (String) config.getInitParameter("params_class");
255 if (params_name == null)
256 {
[24019]257 this.params = new GSParams();
[24753]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());
[24019]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();
[24753]275
[24019]276 }
[18223]277
[24753]278 private void logUsageInfo(HttpServletRequest request)
279 {
280 String usageInfo = "";
[14524]281
[24019]282 //session-info: get params stored in the session
283 HttpSession session = request.getSession(true);
284 Enumeration attributeNames = session.getAttributeNames();
[24753]285 while (attributeNames.hasMoreElements())
286 {
287 String name = (String) attributeNames.nextElement();
288 usageInfo += name + "=" + session.getAttribute(name) + " ";
[24019]289 }
[24753]290
[24019]291 //logged info = general-info + session-info
[24753]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
[24019]299 logger.info(usageInfo);
[24753]300
[24019]301 }
[23790]302
[24753]303 public class UserSessionCache implements HttpSessionBindingListener
304 {
[23790]305
[24019]306 String session_id = "";
[24753]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 */
[24019]313 protected Hashtable coll_name_params_table = null;
[24753]314
315 public UserSessionCache(String id, Hashtable table)
316 {
317 session_id = id;
318 coll_name_params_table = (table == null) ? new Hashtable() : table;
[24019]319 }
[23790]320
[24753]321 protected void cleanupCache(String coll_name)
322 {
323 if (coll_name_params_table.containsKey(coll_name))
324 {
[24019]325 coll_name_params_table.remove(coll_name);
326 }
327 }
328
[24753]329 protected Hashtable getParamsTable()
330 {
[24019]331 return coll_name_params_table;
332 }
333
[24753]334 public void valueBound(HttpSessionBindingEvent event)
335 {
[24019]336 // Do nothing
337 }
338
[24753]339 public void valueUnbound(HttpSessionBindingEvent event)
340 {
341 if (session_ids_table.containsKey(session_id))
342 {
[24019]343 session_ids_table.remove(session_id);
344 }
345 }
346
[24753]347 public int tableSize()
348 {
349 return (coll_name_params_table == null) ? 0 : coll_name_params_table.size();
[24019]350 }
351
352 }
353
[24753]354 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
355 {
356 logUsageInfo(request);
[24019]357
[24753]358 String query_string;
[24962]359 if (request.getMethod().equals("GET"))
[24753]360 {
[24962]361 query_string = request.getQueryString();
[24753]362 }
[24962]363 else if (request.getMethod().equals("POST"))
[24753]364 {
365 query_string = "";
366 Map paramMap = request.getParameterMap();
367 Iterator keyIter = paramMap.keySet().iterator();
[24962]368
369 while (keyIter.hasNext())
[24753]370 {
[24962]371 String current = (String) keyIter.next();
372 query_string += current + "=" + ((String[]) paramMap.get(current))[0];
373 if (keyIter.hasNext())
[24753]374 {
375 query_string += "&";
376 }
377 }
[24962]378
[24753]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
[24962]388 String storageLocation = "";
389 File uploadedFile = null;
[24753]390 try
391 {
392 List items = uploadHandler.parseRequest(request);
393 Iterator iter = items.iterator();
[24962]394 while (iter.hasNext())
[24753]395 {
396 FileItem current = (FileItem) iter.next();
[24962]397 if (current.isFormField())
[24753]398 {
399 query_string += current.getFieldName() + "=" + current.getString();
[24962]400 if (iter.hasNext())
[24753]401 {
402 query_string += "&";
403 }
[24967]404
405 if (current.getFieldName().equals(GSParams.FILE_LOCATION))
[24962]406 {
407 storageLocation = current.getString();
408 }
[24753]409 }
410 else
411 {
412 File file = new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp" + File.separator + current.getName());
[24962]413 File tmpFolder = new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp");
[24967]414 if (!tmpFolder.exists())
[24962]415 {
416 tmpFolder.mkdirs();
417 }
[24753]418 current.write(file);
[24967]419
[24962]420 uploadedFile = file;
[24753]421 }
422 }
[24967]423
424 if (!storageLocation.equals("") && uploadedFile != null)
[24962]425 {
[24967]426 String[] locations = storageLocation.split(":");
427
428 for (String location : locations)
[24962]429 {
[24967]430 File toFile = new File(GlobalProperties.getGSDL3Home() + location);
431 if (toFile.exists())
432 {
433 File backupFile = new File(toFile.getAbsolutePath() + System.currentTimeMillis());
434
435 logger.info("Backing up file (" + toFile.getAbsolutePath() + ") to " + backupFile.getAbsolutePath());
436 toFile.renameTo(backupFile);
437 }
438
[24962]439 logger.info("Moving uploaded file (" + uploadedFile.getAbsolutePath() + ") to " + toFile.getAbsolutePath());
[24967]440 uploadedFile.renameTo(toFile);
[24962]441 }
442 }
[24753]443 }
[24962]444 catch (Exception e)
[24753]445 {
446 logger.error("Exception in LibraryServlet -> " + e.getMessage());
447 }
[24962]448
449 if (query_string.equals(""))
[24753]450 {
451 query_string = null;
452 }
453 }
454 else
455 {
456 query_string = null;
457 }
[24962]458
[24753]459 if (query_string != null)
460 {
[24019]461 String[] query_arr = StringUtils.split(query_string, "&");
462 boolean redirect = false;
463 String href = null;
464 String rl = null;
465 String[] nameval = new String[2]; // Reuse it for memory efficiency purposes
466
[24753]467 for (int i = 0; i < query_arr.length; i++)
468 {
469 if (query_arr[i].startsWith("el="))
470 {
471 if (query_arr[i].substring(query_arr[i].indexOf("=") + 1, query_arr[i].length()).equals("direct"))
472 {
[24019]473 redirect = true;
474 }
[24753]475 }
476 else if (query_arr[i].startsWith("href="))
477 {
478 href = query_arr[i].substring(query_arr[i].indexOf("=") + 1, query_arr[i].length());
[24019]479 href = StringUtils.replace(href, "%2f", "/");
480 href = StringUtils.replace(href, "%7e", "~");
481 href = StringUtils.replace(href, "%3f", "?");
482 href = StringUtils.replace(href, "%3A", "\\:");
483 }
[24753]484 else if (query_arr[i].startsWith("rl="))
485 {
486 rl = query_arr[i].substring(query_arr[i].indexOf("=") + 1, query_arr[i].length());
487 }
[24019]488 }
489
490 //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
491 //"rl=0" this is an external link
492 //"rl=1" this is an internal link
[24753]493 if ((redirect) && (href != null) && (rl.equals("0")))
494 {// This is an external link, the web page is re-directed to the external URL (&el=&rl=0&href="http://...")
[24019]495 response.setContentType("text/xml");
496 response.sendRedirect(href);
497 }
498 }
[24753]499
[24019]500 // Nested Diagnostic Configurator to identify the client for
[24753]501 HttpSession session = request.getSession(true);
[24019]502 session.setMaxInactiveInterval(session_expiration);
[24753]503 String uid = (String) session.getAttribute(GSXML.USER_ID_ATT);
504 if (uid == null)
505 {
506 uid = "" + getNextUserId();
507 session.setAttribute(GSXML.USER_ID_ATT, uid);
[24019]508 }
[24962]509
[24753]510 request.setCharacterEncoding("UTF-8");
511 response.setContentType("text/html;charset=UTF-8");
512 PrintWriter out = response.getWriter();
513
514 String lang = request.getParameter(GSParams.LANGUAGE);
515 if (lang == null || lang.equals(""))
516 {
[24019]517 // try the session cached lang
[24753]518 lang = (String) session.getAttribute(GSParams.LANGUAGE);
519 if (lang == null || lang.equals(""))
520 {
[24019]521 // still not set, use the default
522 lang = this.default_lang;
523 }
524 }
[24753]525
[24019]526 // set the lang in the session
[24753]527 session.setAttribute(GSParams.LANGUAGE, lang);
528
529 String output = request.getParameter(GSParams.OUTPUT);
530 if (output == null || output.equals(""))
531 {
[24019]532 output = "html"; // uses html by default
533 }
[24753]534
[24019]535 // If server output, force a switch to traditional interface
536 //output = (output.equals("server")) ? "html" : output;
[24753]537
[24019]538 // Force change the output mode if client-side XSLT is supported - server vs. client
539 // BUT only if the library allows client-side transforms
[24753]540 if (supports_client_xslt)
541 {
[24019]542 // MUST be done before the xml_message is built
543 Cookie[] cookies = request.getCookies();
544 Cookie xsltCookie = null;
[24753]545
[24019]546 // The client has cookies enabled and a value set - use it!
[24753]547 if (cookies != null)
548 {
549 for (Cookie c : cookies)
550 {
551 if (c.getName().equals("supportsXSLT"))
552 {
[24019]553 xsltCookie = c;
554 break;
555 }
[23790]556 }
[24019]557 output = (xsltCookie != null && xsltCookie.getValue().equals("true") && output.equals("html")) ? "xsltclient" : output;
[23790]558 }
559 }
[24753]560
[24019]561 // the request to the receptionist
[24753]562 Element xml_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
563 Element xml_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", lang, uid);
564 xml_request.setAttribute(GSXML.OUTPUT_ATT, output);
565
566 xml_message.appendChild(xml_request);
567
568 String action = request.getParameter(GSParams.ACTION);
569 String subaction = request.getParameter(GSParams.SUBACTION);
[24019]570 String collection = request.getParameter(GSParams.COLLECTION);
571 String service = request.getParameter(GSParams.SERVICE);
[13122]572
[24019]573 // We clean up the cache session_ids_table if system
574 // commands are issued (and also don't need to do caching for this request)
575 boolean should_cache = true;
[24753]576 if (action != null && action.equals(GSParams.SYSTEM))
577 {
[24019]578 should_cache = false;
[16938]579
[24019]580 // we may want to remove all collection cache info, or just a specific collection
[24753]581 boolean clean_all = true;
[24019]582 String clean_collection = null;
583 // system commands are to activate/deactivate stuff
584 // collection param is in the sc parameter.
585 // don't like the fact that it is hard coded here
586 String coll = request.getParameter(GSParams.SYSTEM_CLUSTER);
[24753]587 if (coll != null && !coll.equals(""))
588 {
[24019]589 clean_all = false;
590 clean_collection = coll;
[24753]591 }
592 else
593 {
[24019]594 // check other system types
[24753]595 if (subaction.equals("a") || subaction.equals("d"))
596 {
[24019]597 String module_name = request.getParameter("sn");
[24753]598 if (module_name != null && !module_name.equals(""))
599 {
[24019]600 clean_all = false;
601 clean_collection = module_name;
602 }
603 }
604 }
[24753]605 if (clean_all)
606 {
607 session_ids_table = new Hashtable();
[24019]608 session.removeAttribute(GSXML.USER_SESSION_CACHE_ATT);
[24753]609 }
610 else
611 {
[24019]612 // just clean up info for clean_collection
613 ArrayList cache_list = new ArrayList(session_ids_table.values());
[24753]614 for (int i = 0; i < cache_list.size(); i++)
615 {
616 UserSessionCache cache = (UserSessionCache) cache_list.get(i);
[24019]617 cache.cleanupCache(clean_collection);
618 }
[24753]619
[24019]620 }
[16938]621
[24019]622 }
[24753]623
[24019]624 // cache_key is the collection name, or service name
625 String cache_key = collection;
[24753]626 if (cache_key == null || cache_key.equals(""))
627 {
[24019]628 cache_key = service;
629 }
[24753]630
[24019]631 // logger.info("should_cache= " + should_cache);
[16938]632
[24019]633 //clear the collection-specific cache in the session, since we have no way to know whether this session is
634 //about the same collection as the last session or not.
635 Enumeration attributeNames = session.getAttributeNames();
[24753]636 while (attributeNames.hasMoreElements())
637 {
638 String name = (String) attributeNames.nextElement();
639 if (!name.equals(GSXML.USER_SESSION_CACHE_ATT) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT))
640 {
[18223]641
[24019]642 session.removeAttribute(name);
643 }
644 }
[24753]645
[24019]646 UserSessionCache session_cache = null;
[24753]647 Hashtable param_table = null;
[24019]648 Hashtable table = null;
649 String sid = session.getId();
[24753]650 if (should_cache == true && cache_key != null && !cache_key.equals(""))
651 {
652 if (session_ids_table.containsKey(sid))
653 {
654 session_cache = (UserSessionCache) session_ids_table.get(sid);
[24019]655 param_table = session_cache.getParamsTable();
656 logger.info("collections in table: " + tableToString(param_table));
[24753]657 if (param_table.containsKey(cache_key))
658 {
[24019]659 //logger.info("existing table: " + collection);
[24753]660 table = (Hashtable) param_table.get(cache_key);
661 }
662 else
663 {
[24019]664 table = new Hashtable();
665 param_table.put(cache_key, table);
666 //logger.info("new table: " + collection);
667 }
[24753]668 }
669 else
670 {
[24019]671 param_table = new Hashtable();
672 table = new Hashtable();
673 param_table.put(cache_key, table);
674 session_cache = new UserSessionCache(sid, param_table);
675 session_ids_table.put(sid, session_cache);
676 session.setAttribute(GSXML.USER_SESSION_CACHE_ATT, session_cache);
677 //logger.info("new session id");
678 }
679 }
[6301]680
[24753]681 if (action == null || action.equals(""))
682 {
[24019]683 // should we do all the following stuff if using default page?
684 // display the home page - the default page
[24753]685 xml_request.setAttribute(GSXML.ACTION_ATT, "p");
686 xml_request.setAttribute(GSXML.SUBACTION_ATT, PageAction.HOME_PAGE);
[24019]687 }
[24753]688 else
689 {
690 xml_request.setAttribute(GSXML.ACTION_ATT, action);
691 if (subaction != null)
692 {
693 xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction);
[24019]694 }
[24753]695
[24019]696 // create the param list for the greenstone request - includes
697 // the params from the current request and any others from the saved session
[24753]698 Element xml_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
699 xml_request.appendChild(xml_param_list);
700
701 Enumeration params = request.getParameterNames();
702 while (params.hasMoreElements())
703 {
704 String name = (String) params.nextElement();
705 if (!name.equals(GSParams.ACTION) && !name.equals(GSParams.SUBACTION) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSParams.OUTPUT))
706 {// we have already dealt with these
707
708 String value = "";
709 String[] values = request.getParameterValues(name);
[24019]710 value = values[0];
[24753]711 if (values.length > 1)
712 {
713 for (int i = 1; i < values.length; i++)
714 {
715 value += "," + values[i];
[24019]716 }
717 }
718 // either add it to the param list straight away, or save it to the session and add it later
[24753]719 if (this.params.shouldSave(name) && table != null)
720 {
[24019]721 table.put(name, value);
722 }
[24753]723 else
724 {
725 Element param = this.doc.createElement(GSXML.PARAM_ELEM);
726 param.setAttribute(GSXML.NAME_ATT, name);
727 param.setAttribute(GSXML.VALUE_ATT, GSXML.xmlSafe(value));
728 xml_param_list.appendChild(param);
729 }
[24019]730 }
731 }
732 //put everything in the table into the session
733 // do we need to do this? why not just put from table into param list
[24753]734 if (table != null)
735 {
736 Enumeration keys = table.keys();
737 while (keys.hasMoreElements())
738 {
739 String name = (String) keys.nextElement();
740 session.setAttribute(name, (String) table.get(name));
[24019]741 }
742 }
[24753]743
[24019]744 // put in all the params from the session cache
[24753]745 params = session.getAttributeNames();
746 while (params.hasMoreElements())
747 {
748 String name = (String) params.nextElement();
[18223]749
[24753]750 if (!name.equals(GSXML.USER_SESSION_CACHE_ATT) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT))
751 {
752
[24019]753 // lang and uid are stored but we dont want it in the param list cos its already in the request
[24753]754 Element param = this.doc.createElement(GSXML.PARAM_ELEM);
755 param.setAttribute(GSXML.NAME_ATT, name);
756 String value = GSXML.xmlSafe((String) session.getAttribute(name));
[18223]757
[24019]758 // ugly hack to undo : escaping
759 value = StringUtils.replace(value, "%3A", "\\:");
[24753]760 param.setAttribute(GSXML.VALUE_ATT, value);
761 xml_param_list.appendChild(param);
[24019]762 }
763 }
764 }
[24753]765
766 if (!output.equals("html") && !output.equals("server") && !output.equals("xsltclient"))
767 {
768 response.setContentType("text/xml"); // for now use text
[24019]769 }
[24753]770
[24019]771 //Add custom HTTP headers if requested
[24118]772 String httpHeadersParam = request.getParameter(GSParams.HTTPHEADERFIELDS);
773 if (httpHeadersParam != null && httpHeadersParam.length() > 0)
774 {
775 Gson gson = new Gson();
[24753]776 Type type = new TypeToken<List<Map<String, String>>>()
777 {
778 }.getType();
779 List<Map<String, String>> httpHeaders = gson.fromJson(httpHeadersParam, type);
780 if (httpHeaders != null && httpHeaders.size() > 0)
781 {
782
783 for (int j = 0; j < httpHeaders.size(); j++)
[24019]784 {
[24753]785 Map nameValueMap = (Map) httpHeaders.get(j);
786 String name = (String) nameValueMap.get("name");
787 String value = (String) nameValueMap.get("value");
788
789 if (name != null && value != null)
[24118]790 {
791 response.setHeader(name, value);
792 }
[24019]793 }
794 }
795 }
[24753]796
[24019]797 Node xml_result = this.recept.process(xml_message);
[24753]798 encodeURLs(xml_result, response);
799 out.println(this.converter.getPrettyString(xml_result));
800
[24019]801 displaySize(session_ids_table);
[16938]802
[24019]803 } //end of doGet(HttpServletRequest, HttpServletResponse)
[18223]804
[24019]805 //a debugging method
[24753]806 private void displaySize(Hashtable table)
807 {
808 if (table == null)
809 {
[24019]810 logger.info("cached table is null");
811 return;
812 }
[24753]813 if (table.size() == 0)
814 {
[24019]815 logger.info("cached table size is zero");
816 return;
817 }
818 int num_cached_coll = 0;
819 ArrayList cache_list = new ArrayList(table.values());
[24753]820 for (int i = 0; i < cache_list.size(); i++)
821 {
822 num_cached_coll += ((UserSessionCache) cache_list.get(i)).tableSize();
[24019]823 }
824 logger.info("Number of sessions : total number of cached collection info = " + table.size() + " : " + num_cached_coll);
825 }
[18223]826
[24019]827 /** merely a debugging method! */
[24753]828 private String tableToString(Hashtable table)
829 {
[24019]830 String str = "";
[24753]831 Enumeration keys = table.keys();
832 while (keys.hasMoreElements())
833 {
834 String name = (String) keys.nextElement();
[24019]835 str += name + ", ";
836 }
837 return str;
838 }
[6301]839
[24753]840 /**
841 * this goes through each URL and adds in a session id if needed-- its
842 * needed if the browser doesn't accept cookies also escapes things if
843 * needed
844 */
845 protected void encodeURLs(Node dataNode, HttpServletResponse response)
846 {
847
848 if (dataNode == null)
849 {
[24019]850 return;
851 }
[16515]852
[24753]853 Element data = null;
[16515]854
[24019]855 short nodeType = dataNode.getNodeType();
[24753]856 if (nodeType == Node.DOCUMENT_NODE)
857 {
858 Document docNode = (Document) dataNode;
859 data = docNode.getDocumentElement();
[24019]860 }
[24753]861 else
862 {
863 data = (Element) dataNode;
[24019]864 }
[16515]865
[24753]866 if (data != null)
867 {
[19984]868
[24019]869 // get all the <a> elements
870 NodeList hrefs = data.getElementsByTagName("a");
871 // Instead of calculating each iteration...
872 int hrefscount = hrefs.getLength();
[23790]873
[24753]874 for (int i = 0; hrefs != null && i < hrefscount; i++)
875 {
876 Element a = (Element) hrefs.item(i);
[24019]877 // ugly hack to get rid of : in the args - interferes with session handling
878 String href = a.getAttribute("href");
[24753]879 if (!href.equals(""))
880 {
881 if (href.indexOf("?") != -1)
882 {
[24019]883 String[] parts = StringUtils.split(href, "\\?", -1);
884 if (parts.length == 1)
885 {
886 parts[0] = StringUtils.replace(parts[0], ":", "%3A");
[24753]887 href = "?" + parts[0];
[24019]888 }
889 else
890 {
891 parts[1] = StringUtils.replace(parts[1], ":", "%3A");
[24753]892 href = parts[0] + "?" + parts[1];
[24019]893 }
[24753]894
[24019]895 }
896 a.setAttribute("href", response.encodeURL(href));
897 }
898 }
[24753]899
[24019]900 // now find any submit bits - get all the <form> elements
901 NodeList forms = data.getElementsByTagName("form");
902 int formscount = forms.getLength();
[24753]903 for (int i = 0; forms != null && i < formscount; i++)
904 {
905 Element form = (Element) forms.item(i);
[24019]906 form.setAttribute("action", response.encodeURL(form.getAttribute("action")));
907 }
908 // are these the only cases where URLs occur??
909 // we should only do this for greenstone urls?
[19984]910 }
[24753]911
[19984]912 }
[18223]913
[24753]914 synchronized protected int getNextUserId()
915 {
[24019]916 next_user_id++;
917 return next_user_id;
918 }
[18223]919
[24753]920 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
921 {
922 doGet(request, response);
[24019]923 }
[3309]924}
Note: See TracBrowser for help on using the repository browser.