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

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

Second round of changes adding in the login ability, also interface options are now returned whenever site metadata is returned

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