tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject svn commit: r529444 - in /tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager: HTMLManagerServlet.java JspHelper.java util/ util/BaseSessionComparator.java util/ReverseComparator.java util/SessionUtils.java
Date Mon, 16 Apr 2007 23:30:56 GMT
Author: remm
Date: Mon Apr 16 16:30:55 2007
New Revision: 529444

URL: http://svn.apache.org/viewvc?view=rev&rev=529444
Log:
- Add session browser capabilities in the manager. Let me know if it creates problems (I checked
XSS to some extent to,
  but please double check if you can).
- Submitted by C├ędrik Lime.

Added:
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/JspHelper.java   (with props)
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/BaseSessionComparator.java
  (with props)
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/ReverseComparator.java   (with
props)
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/SessionUtils.java   (with props)
Modified:
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java?view=diff&rev=529444&r1=529443&r2=529444
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java Mon Apr
16 16:30:55 2007
@@ -23,6 +23,10 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -30,9 +34,14 @@
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
 
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
+import org.apache.catalina.Session;
+import org.apache.catalina.manager.util.BaseSessionComparator;
+import org.apache.catalina.manager.util.ReverseComparator;
+import org.apache.catalina.manager.util.SessionUtils;
 import org.apache.catalina.util.RequestUtil;
 import org.apache.catalina.util.ServerInfo;
 import org.apache.tomcat.util.http.fileupload.DiskFileUpload;
@@ -50,7 +59,7 @@
 * makes it easier to administrate.
 * <p>
 * However if you use a software that parses the output of
-* <code>ManagerServlet</code you won't be able to upgrade
+* <code>ManagerServlet</code> you won't be able to upgrade
 * to this Servlet since the output are not in the
 * same format ar from <code>ManagerServlet</code>
 *
@@ -63,6 +72,11 @@
 
 public final class HTMLManagerServlet extends ManagerServlet {
 
+    protected static final String APPLICATION_MESSAGE = "message";
+    protected static final String APPLICATION_ERROR = "error";
+    protected String sessionsListJspPath  = "/sessionsList.jsp";
+    protected String sessionDetailJspPath = "/sessionDetail.jsp";
+
     // --------------------------------------------------------- Public Methods
 
     /**
@@ -100,7 +114,15 @@
         } else if (command.equals("/undeploy")) {
             message = undeploy(path);
         } else if (command.equals("/sessions")) {
-            message = sessions(path);
+            //message = sessions(path);
+            try {
+                doSessions(path, request, response);
+                return;
+            } catch (Exception e) {
+                log("HTMLManagerServlet.sessions[" + path + "]", e);
+                message = sm.getString("managerServlet.exception",
+                        e.toString());
+            }
         } else if (command.equals("/start")) {
             message = start(path);
         } else if (command.equals("/stop")) {
@@ -562,6 +584,309 @@
         return stringWriter.toString();
     }
 
+    /**
+     * @see javax.servlet.Servlet#getServletInfo()
+     */
+    public String getServletInfo() {
+        return "HTMLManagerServlet, Copyright (c) The Apache Software Foundation";
+    }   
+    
+    /**
+     * @see javax.servlet.GenericServlet#init()
+     */
+    public void init() throws ServletException {
+        super.init();
+    }   
+
+    // ------------------------------------------------ Sessions administration
+
+    /**
+     * 
+     * @param req
+     * @param resp
+     * @throws ServletException
+     * @throws IOException 
+     */
+    protected void doSessions(String path, HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+        req.setAttribute("path", path);
+        String action = req.getParameter("action");
+        if (debug >= 1) {
+            log("sessions: Session action '" + action + "' for web application at '" + path
+ "'");
+        }
+        if ("sessionDetail".equals(action)) {
+	        String sessionId = req.getParameter("sessionId");
+	        displaySessionDetailPage(req, resp, path, sessionId);
+	        return;
+        } else if ("invalidateSessions".equals(action)) {
+            String[] sessionIds = req.getParameterValues("sessionIds");
+            int i = invalidateSessions(path, sessionIds);
+            req.setAttribute(APPLICATION_MESSAGE, "" + i + " sessions invalidated.");
+        } else if ("removeSessionAttribute".equals(action)) {
+            String sessionId = req.getParameter("sessionId");
+            String name = req.getParameter("attributeName");
+            boolean removed = removeSessionAttribute(path, sessionId, name);
+            String outMessage = removed ? "Session attribute '" + name + "' removed." : "Session
did not contain any attribute named '" + name + "'";
+            req.setAttribute(APPLICATION_MESSAGE, outMessage);
+            resp.sendRedirect(resp.encodeRedirectURL(req.getRequestURL().append("?path=").append(path).append("&action=sessionDetail&sessionId=").append(sessionId).toString()));
+            return;
+        } // else
+        displaySessionsListPage(path, req, resp);
+    }
+
+    protected Session[] getSessionsForPath(String path) {
+        if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
+            throw new IllegalArgumentException(sm.getString("managerServlet.invalidPath",
+                                        RequestUtil.filter(path)));
+        }
+        String displayPath = path;
+        if( path.equals("/") )
+            path = "";
+        Context context = (Context) host.findChild(path);
+        if (null == context) {
+            throw new IllegalArgumentException(sm.getString("managerServlet.noContext",
+                                        RequestUtil.filter(displayPath)));
+        }
+        Session[] sessions = context.getManager().findSessions();
+        return sessions;
+    }
+    protected Session getSessionForPathAndId(String path, String id) throws IOException {
+        if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
+            throw new IllegalArgumentException(sm.getString("managerServlet.invalidPath",
+                                        RequestUtil.filter(path)));
+        }
+        String displayPath = path;
+        if( path.equals("/") )
+            path = "";
+        Context context = (Context) host.findChild(path);
+        if (null == context) {
+            throw new IllegalArgumentException(sm.getString("managerServlet.noContext",
+                                        RequestUtil.filter(displayPath)));
+        }
+        Session session = context.getManager().findSession(id);
+        return session;
+    }
+
+    /**
+     * 
+     * @param req
+     * @param resp
+     * @throws ServletException
+     * @throws IOException
+     */
+    protected void displaySessionsListPage(String path, HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException {
+        List/*<Session>*/ activeSessions = Arrays.asList(getSessionsForPath(path));
+        String sortBy = req.getParameter("sort");
+        String orderBy = null;
+        if (null != sortBy && !"".equals(sortBy.trim())) {
+            Comparator comparator = getComparator(sortBy);
+            if (comparator != null) {
+                orderBy = req.getParameter("order");
+                if ("DESC".equalsIgnoreCase(orderBy)) {
+                    comparator = new ReverseComparator(comparator);
+                    // orderBy = "ASC";
+                } else {
+                    //orderBy = "DESC";
+                }
+                try {
+					Collections.sort(activeSessions, comparator);
+				} catch (IllegalStateException ise) {
+					// at least 1 of the sessions is invalidated
+					req.setAttribute(APPLICATION_ERROR, "Can't sort session list: one session is invalidated");
+				}
+            } else {
+                log("WARNING: unknown sort order: " + sortBy);
+            }
+        }
+        // keep sort order
+        req.setAttribute("sort", sortBy);
+        req.setAttribute("order", orderBy);
+        req.setAttribute("activeSessions", activeSessions);
+        //strong>NOTE</strong> - This header will be overridden
+        // automatically if a <code>RequestDispatcher.forward()</code> call is
+        // ultimately invoked.
+        resp.setHeader("Pragma", "No-cache"); // HTTP 1.0
+        resp.setHeader("Cache-Control", "no-cache,no-store,max-age=0"); // HTTP 1.1
+        resp.setDateHeader("Expires", 0); // 0 means now
+        getServletContext().getRequestDispatcher(sessionsListJspPath).include(req, resp);
+    }
+
+    /**
+     * 
+     * @param req
+     * @param resp
+     * @throws ServletException
+     * @throws IOException
+     */
+    protected void displaySessionDetailPage(HttpServletRequest req, HttpServletResponse resp,
String path, String sessionId) throws ServletException, IOException {
+        Session session = getSessionForPathAndId(path, sessionId);
+        //strong>NOTE</strong> - This header will be overridden
+        // automatically if a <code>RequestDispatcher.forward()</code> call is
+        // ultimately invoked.
+        resp.setHeader("Pragma", "No-cache"); // HTTP 1.0
+        resp.setHeader("Cache-Control", "no-cache,no-store,max-age=0"); // HTTP 1.1
+        resp.setDateHeader("Expires", 0); // 0 means now
+        req.setAttribute("currentSession", session);
+        getServletContext().getRequestDispatcher(sessionDetailJspPath).include(req, resp);
+    }
+
+    /**
+     * Invalidate HttpSessions
+     * @param sessionIds
+     * @return number of invalidated sessions
+     * @throws IOException 
+     */
+    public int invalidateSessions(String path, String[] sessionIds) throws IOException {
+        if (null == sessionIds) {
+            return 0;
+        }
+        int nbAffectedSessions = 0;
+        for (int i = 0; i < sessionIds.length; ++i) {
+            String sessionId = sessionIds[i];
+            HttpSession session = getSessionForPathAndId(path, sessionId).getSession();
+            if (null == session) {
+                // Shouldn't happen, but let's play nice...
+            	if (debug >= 1) {
+            		log("WARNING: can't invalidate null session " + sessionId);
+            	}
+                continue;
+            }
+            try {
+				session.invalidate();
+				++nbAffectedSessions;
+	            if (debug >= 1) {
+	                log("Invalidating session id " + sessionId);
+	            }
+			} catch (IllegalStateException ise) {
+				if (debug >= 1) {
+					log("Can't invalidate already invalidated session id " + sessionId);
+				}
+			}
+        }
+        return nbAffectedSessions;
+    }
+
+    /**
+     * Removes an attribute from an HttpSession
+     * @param sessionId
+     * @param attributeName
+     * @return true if there was an attribute removed, false otherwise
+     * @throws IOException 
+     */
+    public boolean removeSessionAttribute(String path, String sessionId, String attributeName)
throws IOException {
+        HttpSession session = getSessionForPathAndId(path, sessionId).getSession();
+        if (null == session) {
+            // Shouldn't happen, but let's play nice...
+        	if (debug >= 1) {
+        		log("WARNING: can't remove attribute '" + attributeName + "' for null session "
+ sessionId);
+        	}
+            return false;
+        }
+        boolean wasPresent = (null != session.getAttribute(attributeName));
+        try {
+            session.removeAttribute(attributeName);
+        } catch (IllegalStateException ise) {
+        	if (debug >= 1) {
+        		log("Can't remote attribute '" + attributeName + "' for invalidated session id
" + sessionId);
+        	}
+        }
+        return wasPresent;
+    }
+
+    /**
+     * Sets the maximum inactive interval (session timeout) an HttpSession
+     * @param sessionId
+     * @param maxInactiveInterval in seconds
+     * @return old value for maxInactiveInterval
+     * @throws IOException 
+     */
+    public int setSessionMaxInactiveInterval(String path, String sessionId, int maxInactiveInterval)
throws IOException {
+        HttpSession session = getSessionForPathAndId(path, sessionId).getSession();
+        if (null == session) {
+            // Shouldn't happen, but let's play nice...
+        	if (debug >= 1) {
+        		log("WARNING: can't set timout for null session " + sessionId);
+        	}
+            return 0;
+        }
+        try {
+			int oldMaxInactiveInterval = session.getMaxInactiveInterval();
+			session.setMaxInactiveInterval(maxInactiveInterval);
+			return oldMaxInactiveInterval;
+        } catch (IllegalStateException ise) {
+        	if (debug >= 1) {
+        		log("Can't set MaxInactiveInterval '" + maxInactiveInterval + "' for invalidated
session id " + sessionId);
+        	}
+        	return 0;
+		}
+    }
+
+    protected Comparator getComparator(String sortBy) {
+        Comparator comparator = null;
+        if ("CreationTime".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return new Date(session.getCreationTime());
+                }
+            };
+        } else if ("id".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return session.getId();
+                }
+            };
+        } else if ("LastAccessedTime".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return new Date(session.getLastAccessedTime());
+                }
+            };
+        } else if ("MaxInactiveInterval".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return new Date(session.getMaxInactiveInterval());
+                }
+            };
+        } else if ("new".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return Boolean.valueOf(session.getSession().isNew());
+                }
+            };
+        } else if ("locale".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return JspHelper.guessDisplayLocaleFromSession(session);
+                }
+            };
+        } else if ("user".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return JspHelper.guessDisplayUserFromSession(session);
+                }
+            };
+        } else if ("UsedTime".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return new Date(SessionUtils.getUsedTimeForSession(session));
+                }
+            };
+        } else if ("InactiveTime".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return new Date(SessionUtils.getInactiveTimeForSession(session));
+                }
+            };
+        } else if ("TTL".equalsIgnoreCase(sortBy)) {
+            comparator = new BaseSessionComparator() {
+                public Comparable getComparableObject(Session session) {
+                    return new Date(SessionUtils.getTTLForSession(session));
+                }
+            };
+        }
+        //TODO: complete this to TTL, etc.
+        return comparator;
+    }
+
     // ------------------------------------------------------ Private Constants
 
     // These HTML sections are broken in relatively small sections, because of
@@ -586,7 +911,7 @@
         " <td class=\"row-left\" bgcolor=\"{5}\"><small><a href=\"{0}\">{0}</a></small></td>\n"
+
         " <td class=\"row-left\" bgcolor=\"{5}\"><small>{1}</small></td>\n"
+
         " <td class=\"row-center\" bgcolor=\"{5}\"><small>{2}</small></td>\n"
+
-        " <td class=\"row-center\" bgcolor=\"{5}\"><small><a href=\"{3}\">{4}</a></small></td>\n";
+        " <td class=\"row-center\" bgcolor=\"{5}\"><small><a href=\"{3}\"
target=\"_new\">{4}</a></small></td>\n";
 
     private static final String MANAGER_APP_ROW_BUTTON_SECTION =
         " <td class=\"row-left\" bgcolor=\"{8}\">\n" +

Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/JspHelper.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/JspHelper.java?view=auto&rev=529444
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/JspHelper.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/JspHelper.java Mon Apr 16 16:30:55
2007
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.manager;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.catalina.Session;
+import org.apache.catalina.manager.util.SessionUtils;
+
+
+/**
+ * Helper JavaBean for JSPs, because JSTL 1.1/EL 2.0 is too dumb to
+ * to what I need (call methods with parameters), or I am too dumb to use it correctly. :)
+ * @author C&eacute;drik LIME
+ */
+public class JspHelper {
+
+    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+    private static final String DATE_FORMAT = "yyyy-MM-dd";
+    private static final String TIME_FORMAT = "HH:mm:ss";
+
+    /**
+     * Public constructor, so that this class can be considered a JavaBean
+     */
+    private JspHelper() {
+        super();
+    }
+
+    /**
+     * Try to get user locale from the session, if possible.
+     * IMPLEMENTATION NOTE: this method has explicit support for Tapestry 3 and Struts 1.x
+     * @param in_session
+     * @return String
+     */
+    public static String guessDisplayLocaleFromSession(Session in_session) {
+        return localeToString(SessionUtils.guessLocaleFromSession(in_session));
+    }
+    private static String localeToString(Locale locale) {
+        if (locale != null) {
+            return locale.toString();//locale.getDisplayName();
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * Try to get user name from the session, if possible.
+     * @param in_session
+     * @return String
+     */
+    public static String guessDisplayUserFromSession(Session in_session) {
+        Object user = SessionUtils.guessUserFromSession(in_session);
+        return escapeXml(user);
+    }
+
+
+    public static String getDisplayCreationTimeForSession(Session in_session) {
+        try {
+			DateFormat formatter = new SimpleDateFormat(DATE_TIME_FORMAT);
+			return formatter.format(new Date(in_session.getCreationTime()));
+        } catch (IllegalStateException ise) {
+        	//ignore: invalidated session
+        	return "";
+		}
+    }
+
+    public static String getDisplayLastAccessedTimeForSession(Session in_session) {
+        try {
+			DateFormat formatter = new SimpleDateFormat(DATE_TIME_FORMAT);
+			return formatter.format(new Date(in_session.getLastAccessedTime()));
+        } catch (IllegalStateException ise) {
+        	//ignore: invalidated session
+        	return "";
+		}
+    }
+
+    public static String getDisplayUsedTimeForSession(Session in_session) {
+        return secondsToTimeString(SessionUtils.getUsedTimeForSession(in_session)/1000);
+    }
+
+    public static String getDisplayTTLForSession(Session in_session) {
+        return secondsToTimeString(SessionUtils.getTTLForSession(in_session)/1000);
+    }
+
+    public static String getDisplayInactiveTimeForSession(Session in_session) {
+        return secondsToTimeString(SessionUtils.getInactiveTimeForSession(in_session)/1000);
+    }
+
+    public static String secondsToTimeString(long in_seconds) {
+        StringBuffer buff = new StringBuffer(9);
+        long rest = in_seconds;
+        long hour = rest / 3600;
+        rest = rest % 3600;
+        long minute = rest / 60;
+        rest = rest % 60;
+        long second = rest;
+        if (hour < 10) {
+            buff.append('0');
+        }
+        buff.append(hour);
+        buff.append(':');
+        if (minute < 10) {
+            buff.append('0');
+        }
+        buff.append(minute);
+        buff.append(':');
+        if (second < 10) {
+            buff.append('0');
+        }
+        buff.append(second);
+        return buff.toString();
+    }
+
+
+    /**
+    * Following copied from org.apache.taglibs.standard.tag.common.core.OutSupport v1.1.2
+    * 
+    *  Optimized to create no extra objects and write directly
+    *  to the JspWriter using blocks of escaped and unescaped characters
+    *
+    */
+   private static void writeEscapedXml(char[] buffer, int length, Writer w) throws IOException
{
+       int start = 0;
+
+       for (int i = 0; i < length; i++) {
+           char c = buffer[i];
+           if (c <= HIGHEST_SPECIAL) {
+               char[] escaped = specialCharactersRepresentation[c];
+               if (escaped != null) {
+                   // add unescaped portion
+                   if (start < i) {
+                       w.write(buffer,start,i-start);
+                   }
+                   // add escaped xml
+                   w.write(escaped);
+                   start = i + 1;
+               }
+           }
+       }
+       // add rest of unescaped portion
+       if (start < length) {
+           w.write(buffer,start,length-start);
+       }
+   }
+
+
+    /*
+     * Following copied from org.apache.taglibs.standard.tag.common.core.Util v1.1.2
+     */
+
+    private static final int HIGHEST_SPECIAL = '>';
+    private static char[][] specialCharactersRepresentation = new char[HIGHEST_SPECIAL +
1][];
+    static {
+        specialCharactersRepresentation['&'] = "&amp;".toCharArray();
+        specialCharactersRepresentation['<'] = "&lt;".toCharArray();
+        specialCharactersRepresentation['>'] = "&gt;".toCharArray();
+        specialCharactersRepresentation['"'] = "&#034;".toCharArray();
+        specialCharactersRepresentation['\''] = "&#039;".toCharArray();
+    }
+
+    public static String escapeXml(Object obj) {
+    	return obj == null ? "" : escapeXml(String.valueOf(obj));
+    }
+    /**
+     * Performs the following substring replacements
+     * (to facilitate output to XML/HTML pages):
+     *
+     *    & -> &amp;
+     *    < -> &lt;
+     *    > -> &gt;
+     *    " -> &#034;
+     *    ' -> &#039;
+     *
+     * See also OutSupport.writeEscapedXml().
+     */
+    public static String escapeXml(String buffer) {
+    	if (buffer == null) {
+			return "";
+		}
+        int start = 0;
+        int length = buffer.length();
+        char[] arrayBuffer = buffer.toCharArray();
+        StringBuffer escapedBuffer = null;
+
+        for (int i = 0; i < length; i++) {
+            char c = arrayBuffer[i];
+            if (c <= HIGHEST_SPECIAL) {
+                char[] escaped = specialCharactersRepresentation[c];
+                if (escaped != null) {
+                    // create StringBuffer to hold escaped xml string
+                    if (start == 0) {
+                        escapedBuffer = new StringBuffer(length + 5);
+                    }
+                    // add unescaped portion
+                    if (start < i) {
+                        escapedBuffer.append(arrayBuffer,start,i-start);
+                    }
+                    start = i + 1;
+                    // add escaped xml
+                    escapedBuffer.append(escaped);
+                }
+            }
+        }
+        // no xml escaping was necessary
+        if (start == 0) {
+            return buffer;
+        }
+        // add rest of unescaped portion
+        if (start < length) {
+            escapedBuffer.append(arrayBuffer,start,length-start);
+        }
+        return escapedBuffer.toString();
+    }
+
+    public static String formatNumber(long number) {
+    	return NumberFormat.getNumberInstance().format(number);
+    }
+}

Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/JspHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/BaseSessionComparator.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/BaseSessionComparator.java?view=auto&rev=529444
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/BaseSessionComparator.java
(added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/BaseSessionComparator.java
Mon Apr 16 16:30:55 2007
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.manager.util;
+
+import java.util.Comparator;
+
+import org.apache.catalina.Session;
+
+/**
+ * Comparator which permits to compare on a session's content
+ * @author C&eacute;drik LIME
+ */
+public abstract class BaseSessionComparator implements Comparator {
+
+    /**
+     * 
+     */
+    public BaseSessionComparator() {
+        super();
+    }
+
+    public abstract Comparable getComparableObject(Session session);
+
+    /* (non-Javadoc)
+     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+     */
+    public final int compare(Object o1, Object o2) {
+        Comparable c1 = getComparableObject((Session)o1);
+        Comparable c2 = getComparableObject((Session)o2);
+        return c1==null ? (c2==null ? 0 : -1) : (c2==null ? 1 : c1.compareTo(c2));
+    }
+}

Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/BaseSessionComparator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/ReverseComparator.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/ReverseComparator.java?view=auto&rev=529444
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/ReverseComparator.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/ReverseComparator.java Mon
Apr 16 16:30:55 2007
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.manager.util;
+
+import java.util.Comparator;
+
+/**
+ * Comparator which reverse the sort order
+ * @author C&eacute;drik LIME
+ */
+public class ReverseComparator implements Comparator {
+    protected Comparator comparator;
+
+    /**
+     * 
+     */
+    public ReverseComparator(Comparator comparator) {
+        super();
+        this.comparator = comparator;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+     */
+    public int compare(Object o1, Object o2) {
+        int returnValue = comparator.compare(o1, o2);
+        return (- returnValue);
+    }
+}

Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/ReverseComparator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/SessionUtils.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/SessionUtils.java?view=auto&rev=529444
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/SessionUtils.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/SessionUtils.java Mon Apr 16
16:30:55 2007
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.manager.util;
+
+import java.lang.reflect.Method;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Locale;
+
+import javax.security.auth.Subject;
+import javax.servlet.http.HttpSession;
+
+import org.apache.catalina.Session;
+
+/**
+ * Utility methods on HttpSessions...
+ * @author C&eacute;drik LIME
+ */
+public class SessionUtils {
+
+    /**
+     * 
+     */
+    private SessionUtils() {
+        super();
+    }
+
+    /**
+     * The session attributes key under which the user's selected
+     * <code>java.util.Locale</code> is stored, if any.
+     */
+    // org.apache.struts.Globals.LOCALE_KEY
+    private static final String STRUTS_LOCALE_KEY = "org.apache.struts.action.LOCALE";//$NON-NLS-1$
+    // javax.servlet.jsp.jstl.core.Config.FMT_LOCALE
+    private static final String JSTL_LOCALE_KEY   = "javax.servlet.jsp.jstl.fmt.locale";//$NON-NLS-1$
+    // org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME
+    private static final String SPRING_LOCALE_KEY = "org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE";//$NON-NLS-1$
+    /**
+     * Lower and upper-case strings will be dynamically generated. Put mid-capitalised strings
here!
+     */
+    private static final String[] LOCALE_TEST_ATTRIBUTES = new String[] {
+        STRUTS_LOCALE_KEY, SPRING_LOCALE_KEY, JSTL_LOCALE_KEY, "Locale", "java.util.Locale"
};
+    /**
+     * Lower and upper-case strings will be dynamically generated. Put mid-capitalised strings
here!
+     */
+    private static final String[] USER_TEST_ATTRIBUTES = new String[] {
+        "Login", "User", "userName", "UserName", "Utilisateur" };
+
+    /**
+     * Try to get user locale from the session, if possible.
+     * IMPLEMENTATION NOTE: this method has explicit support for Tapestry 3, Struts 1.x and
Spring
+     * JSF check the browser meta tag "accept languages" to choose what langage to display.
+     * @param in_session
+     * @return String
+     */
+    public static Locale guessLocaleFromSession(final Session in_session) {
+    	return guessLocaleFromSession(in_session.getSession());
+    }
+    public static Locale guessLocaleFromSession(final HttpSession in_session) {
+    	if (null == in_session) {
+			return null;
+		}
+        try {
+            Locale locale = null;
+            
+	        // First search "known locations"
+	        for (int i = 0; i < LOCALE_TEST_ATTRIBUTES.length; ++i) {
+	            Object obj = in_session.getAttribute(LOCALE_TEST_ATTRIBUTES[i]);
+	            if (null != obj && obj instanceof Locale) {
+	                locale = (Locale) obj;
+	                break;
+	            }
+	            obj = in_session.getAttribute(LOCALE_TEST_ATTRIBUTES[i].toLowerCase());
+	            if (null != obj && obj instanceof Locale) {
+	                locale = (Locale) obj;
+	                break;
+	            }
+	            obj = in_session.getAttribute(LOCALE_TEST_ATTRIBUTES[i].toUpperCase());
+	            if (null != obj && obj instanceof Locale) {
+	                locale = (Locale) obj;
+	                break;
+	            }
+	        }
+	
+	        if (null != locale) {
+	            return locale;
+	        }
+	
+	        // Tapestry 3.0: Engine stored in session under "org.apache.tapestry.engine:" +
config.getServletName()
+	        // TODO: Tapestry 4+
+	        {
+	            final List tapestryArray = new ArrayList();
+	            for (Enumeration enumeration = in_session.getAttributeNames(); enumeration.hasMoreElements();)
{
+	                String name = (String) enumeration.nextElement();
+	                if (name.indexOf("tapestry") > -1 && name.indexOf("engine") >
-1 && null != in_session.getAttribute(name)) {//$NON-NLS-1$ //$NON-NLS-2$
+	                    tapestryArray.add(in_session.getAttribute(name));
+	                }
+	            }
+	            if (tapestryArray.size() == 1) {
+	                // found a potential Engine! Let's call getLocale() on it.
+	                Object probableEngine = tapestryArray.get(0);
+	                if (null != probableEngine) {
+	                    try {
+	                        Method readMethod = probableEngine.getClass().getMethod("getLocale",
null);//$NON-NLS-1$
+	                        if (null != readMethod) {
+	                            // Call the property getter and return the value
+	                            Object possibleLocale = readMethod.invoke(probableEngine, null);
+	                            if (null != possibleLocale && possibleLocale instanceof
Locale) {
+	                                locale = (Locale) possibleLocale;
+	                            }
+	                        }
+	                    } catch (Exception e) {
+	                        // stay silent
+	                    }
+	                }
+	            }
+	        }
+	        
+	        if (null != locale) {
+	            return locale;
+	        }
+	
+	        // Last guess: iterate over all attributes, to find a Locale
+	        // If there is only one, consider it to be /the/ locale
+	        {
+	            final List localeArray = new ArrayList();
+	            for (Enumeration enumeration = in_session.getAttributeNames(); enumeration.hasMoreElements();)
{
+	                String name = (String) enumeration.nextElement();
+	                Object obj = in_session.getAttribute(name);
+	                if (null != obj && obj instanceof Locale) {
+	                    localeArray.add(obj);
+	                }
+	            }
+	            if (localeArray.size() == 1) {
+	                locale = (Locale) localeArray.get(0);
+	            }
+	        }
+
+	        return locale;
+        } catch (IllegalStateException ise) {
+        	//ignore: invalidated session
+        	return null;
+        }
+    }
+
+    /**
+     * Try to get user from the session, if possible.
+     * @param in_session
+     * @return Object
+     */
+    public static Object guessUserFromSession(final Session in_session) {
+    	if (null == in_session) {
+			return null;
+		}
+    	if (in_session.getPrincipal() != null) {
+			return in_session.getPrincipal().getName();
+		}
+    	HttpSession httpSession = in_session.getSession();
+    	try {
+	        Object user = null;
+	        // First search "known locations"
+	        for (int i = 0; i < USER_TEST_ATTRIBUTES.length; ++i) {
+	            Object obj = httpSession.getAttribute(USER_TEST_ATTRIBUTES[i]);
+	            if (null != obj) {
+	                user = obj;
+	                break;
+	            }
+	            obj = httpSession.getAttribute(USER_TEST_ATTRIBUTES[i].toLowerCase());
+	            if (null != obj) {
+	                user = obj;
+	                break;
+	            }
+	            obj = httpSession.getAttribute(USER_TEST_ATTRIBUTES[i].toUpperCase());
+	            if (null != obj) {
+	                user = obj;
+	                break;
+	            }
+	        }
+	
+	        if (null != user) {
+	            return user;
+	        }
+	
+	        // Last guess: iterate over all attributes, to find a java.security.Principal or
javax.security.auth.Subject
+	        // If there is only one, consider it to be /the/ user
+	        {
+	            final List principalArray = new ArrayList();
+	            for (Enumeration enumeration = httpSession.getAttributeNames(); enumeration.hasMoreElements();)
{
+	                String name = (String) enumeration.nextElement();
+	                Object obj = httpSession.getAttribute(name);
+	                if (null != obj && (obj instanceof Principal || obj instanceof Subject))
{
+	                    principalArray.add(obj);
+	                }
+	                // This workaround for JDK 1.3 compatibility. For JDK 1.4+, use previous
(commented) instanceof.
+//	                try {
+//	                    Class subjectClass = Class.forName("javax.security.auth.Subject",
true, Thread.currentThread().getContextClassLoader());
+//	                    if (subjectClass.isInstance(obj)) {
+//	                        principalArray.add(obj);
+//	                    }
+//	                } catch (ClassNotFoundException cnfe) {
+//	                    // This is JDK 1.3: javax.security.auth.Subject does not exist; do
nothing
+//	                }
+	            }
+	            if (principalArray.size() == 1) {
+	                user = principalArray.get(0);
+	            }
+	        }
+	
+	        if (null != user) {
+	            return user;
+	        }
+
+	        return user;
+        } catch (IllegalStateException ise) {
+        	//ignore: invalidated session
+        	return null;
+        }
+    }
+
+
+    public static long getUsedTimeForSession(Session in_session) {
+        try {
+			long diffMilliSeconds = in_session.getLastAccessedTime() - in_session.getCreationTime();
+			return diffMilliSeconds;
+        } catch (IllegalStateException ise) {
+        	//ignore: invalidated session
+        	return -1;
+		}
+    }
+
+    public static long getTTLForSession(Session in_session) {
+        try {
+			long diffMilliSeconds = (1000*in_session.getMaxInactiveInterval()) - (System.currentTimeMillis()
- in_session.getLastAccessedTime());
+			return diffMilliSeconds;
+        } catch (IllegalStateException ise) {
+        	//ignore: invalidated session
+        	return -1;
+		}
+    }
+
+    public static long getInactiveTimeForSession(Session in_session) {
+        try {
+			long diffMilliSeconds =  System.currentTimeMillis() - in_session.getLastAccessedTime();
+			return diffMilliSeconds;
+        } catch (IllegalStateException ise) {
+        	//ignore: invalidated session
+        	return -1;
+		}
+    }
+}

Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/manager/util/SessionUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message