/* * UIUtil.java * * Version: $Revision: 4662 $ * * Date: $Date: 2010-01-08 03:27:08 +0000 (Fri, 08 Jan 2010) $ * * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts * Institute of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Hewlett-Packard Company nor the name of the * Massachusetts Institute of Technology nor the names of their * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.dspace.app.webui.util; import java.io.PrintWriter; import java.io.StringWriter; import java.sql.SQLException; import java.util.Date; import java.util.Enumeration; import java.util.Locale; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.jsp.jstl.core.Config; import org.apache.log4j.Logger; import org.dspace.app.util.Util; import org.dspace.authenticate.AuthenticationManager; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.DCDate; import org.dspace.core.ConfigurationManager; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.core.Email; import org.dspace.core.I18nUtil; import org.dspace.eperson.EPerson; /** * Miscellaneous UI utility methods * * @author Robert Tansley * @version $Revision: 4662 $ */ public class UIUtil extends Util { /** log4j category */ public static Logger log = Logger.getLogger(UIUtil.class); /** * Obtain a new context object. If a context object has already been created * for this HTTP request, it is re-used, otherwise it is created. If a user * has authenticated with the system, the current user of the context is set * appropriately. * * @param request * the HTTP request * * @return a context object */ public static Context obtainContext(HttpServletRequest request) throws SQLException { //Set encoding to UTF-8, if not set yet //This avoids problems of using the HttpServletRequest //in the getSpecialGroups() for an AuthenticationMethod, //which causes the HttpServletRequest to default to //non-UTF-8 encoding. try { if(request.getCharacterEncoding()==null) request.setCharacterEncoding(Constants.DEFAULT_ENCODING); } catch(Exception e) { log.error("Unable to set encoding to UTF-8.", e); } Context c = (Context) request.getAttribute("dspace.context"); if (c == null) { // No context for this request yet c = new Context(); HttpSession session = request.getSession(); // See if a user has authentication Integer userID = (Integer) session.getAttribute( "dspace.current.user.id"); if (userID != null) { String remAddr = (String)session.getAttribute("dspace.current.remote.addr"); if (remAddr != null && remAddr.equals(request.getRemoteAddr())) { EPerson e = EPerson.find(c, userID.intValue()); Authenticate.loggedIn(c, request, e); } else { log.warn("POSSIBLE HIJACKED SESSION: request from "+ request.getRemoteAddr()+" does not match original "+ "session address: "+remAddr+". Authentication rejected."); } } // Set any special groups - invoke the authentication mgr. int[] groupIDs = AuthenticationManager.getSpecialGroups(c, request); for (int i = 0; i < groupIDs.length; i++) { c.setSpecialGroup(groupIDs[i]); log.debug("Adding Special Group id="+String.valueOf(groupIDs[i])); } // Set the session ID and IP address c.setExtraLogInfo("session_id=" + request.getSession().getId() + ":ip_addr=" + request.getRemoteAddr()); // Store the context in the request request.setAttribute("dspace.context", c); } // Set the locale to be used Locale sessionLocale = getSessionLocale(request); Config.set(request.getSession(), Config.FMT_LOCALE, sessionLocale); c.setCurrentLocale(sessionLocale); return c; } /** * Get the current community location, that is, where the user "is". This * returns <code>null</code> if there is no location, i.e. "all of DSpace" * is the location. * * @param request * current HTTP request * * @return the current community location, or null */ public static Community getCommunityLocation(HttpServletRequest request) { return ((Community) request.getAttribute("dspace.community")); } /** * Get the current collection location, that is, where the user "is". This * returns null if there is no collection location, i.e. the location is * "all of DSpace" or a community. * * @param request * current HTTP request * * @return the current collection location, or null */ public static Collection getCollectionLocation(HttpServletRequest request) { return ((Collection) request.getAttribute("dspace.collection")); } /** * Put the original request URL into the request object as an attribute for * later use. This is necessary because forwarding a request removes this * information. The attribute is only written if it hasn't been before; thus * it can be called after a forward safely. * * @param request * the HTTP request */ public static void storeOriginalURL(HttpServletRequest request) { String orig = (String) request.getAttribute("dspace.original.url"); if (orig == null) { String fullURL = request.getRequestURL().toString(); if (request.getQueryString() != null) { fullURL = fullURL + "?" + request.getQueryString(); } request.setAttribute("dspace.original.url", fullURL); } } /** * Get the original request URL. * * @param request * the HTTP request * * @return the original request URL */ public static String getOriginalURL(HttpServletRequest request) { // Make sure there's a URL in the attribute storeOriginalURL(request); return ((String) request.getAttribute("dspace.original.url")); } /** * Write a human-readable version of a DCDate. * * @param d * the date * @param time * if true, display the time with the date * @param localTime * if true, adjust for local timezone, otherwise GMT * @param request * the servlet request * * @return the date in a human-readable form. */ public static String displayDate(DCDate d, boolean time, boolean localTime, HttpServletRequest request) { return d.displayDate(time, localTime, getSessionLocale(request)); } /** * Return a string for logging, containing useful information about the * current request - the URL, the method and parameters. * * @param request * the request object. * @return a multi-line string containing information about the request. */ public static String getRequestLogInfo(HttpServletRequest request) { String report; report = "-- URL Was: " + getOriginalURL(request) + "\n"; report = report + "-- Method: " + request.getMethod() + "\n"; // First write the parameters we had report = report + "-- Parameters were:\n"; Enumeration e = request.getParameterNames(); while (e.hasMoreElements()) { String name = (String) e.nextElement(); if (name.equals("login_password")) { // We don't want to write a clear text password // to the log, even if it's wrong! report = report + "-- " + name + ": *not logged*\n"; } else { report = report + "-- " + name + ": \"" + request.getParameter(name) + "\"\n"; } } return report; } /** * Get the Locale for a session according to the user's language selection or language preferences. * Order of selection * - language selected via UI * - language as set by application * - language browser default * * @param request * the request Object * @return supportedLocale * Locale supported by this DSpace Instance for this request */ public static Locale getSessionLocale(HttpServletRequest request) { String paramLocale = request.getParameter("locale"); Locale sessionLocale = null; Locale supportedLocale = null; if (paramLocale != null && paramLocale != "") { /* get session locale according to user selection */ sessionLocale = new Locale(paramLocale); } if (sessionLocale == null) { /* get session locale set by application */ HttpSession session = request.getSession(); sessionLocale = (Locale) Config.get(session, Config.FMT_LOCALE); } /* * if session not set by selection or application then default browser * locale */ if (sessionLocale == null) { sessionLocale = request.getLocale(); } if (sessionLocale == null) { sessionLocale = I18nUtil.DEFAULTLOCALE; } supportedLocale = I18nUtil.getSupportedLocale(sessionLocale); return supportedLocale; } /** * Send an alert to the designated "alert recipient" - that is, when a * database error or internal error occurs, this person is sent an e-mail * with details. * <P> * The recipient is configured via the "alert.recipient" property in * <code>dspace.cfg</code>. If this property is omitted, no alerts are * sent. * <P> * This method "swallows" any exception that might occur - it will just be * logged. This is because this method will usually be invoked as part of an * error handling routine anyway. * * @param request * the HTTP request leading to the error * @param exception * the exception causing the error, or null */ public static void sendAlert(HttpServletRequest request, Exception exception) { String logInfo = UIUtil.getRequestLogInfo(request); Context c = (Context) request.getAttribute("dspace.context"); Locale locale = getSessionLocale(request); EPerson user = null; try { String recipient = ConfigurationManager .getProperty("alert.recipient"); if (recipient != null) { Email email = ConfigurationManager.getEmail(I18nUtil.getEmailFilename(locale, "internal_error")); email.addRecipient(recipient); email.addArgument(ConfigurationManager .getProperty("dspace.url")); email.addArgument(new Date()); email.addArgument(request.getSession().getId()); email.addArgument(logInfo); String stackTrace; if (exception != null) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); exception.printStackTrace(pw); pw.flush(); stackTrace = sw.toString(); } else { stackTrace = "No exception"; } email.addArgument(stackTrace); try { user = c.getCurrentUser(); } catch (Exception e) { log.warn("No context, the database might be down or the connection pool exhausted."); } if (user != null) { email.addArgument(user.getFullName() + " (" + user.getEmail() + ")"); } else { email.addArgument("Anonymous"); } email.addArgument(request.getRemoteAddr()); email.send(); } } catch (Exception e) { // Not much we can do here! log.warn("Unable to send email alert", e); } } }