Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » manager » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   
   19   package org.apache.catalina.manager;
   20   
   21   import java.io.File;
   22   import java.io.IOException;
   23   import java.io.PrintWriter;
   24   import java.io.StringWriter;
   25   import java.text.MessageFormat;
   26   import java.util.Arrays;
   27   import java.util.Collections;
   28   import java.util.Comparator;
   29   import java.util.Date;
   30   import java.util.Iterator;
   31   import java.util.List;
   32   import java.util.Map;
   33   import java.util.TreeMap;
   34   import javax.servlet.ServletException;
   35   import javax.servlet.http.HttpServletRequest;
   36   import javax.servlet.http.HttpServletResponse;
   37   import javax.servlet.http.HttpSession;
   38   
   39   import org.apache.catalina.Container;
   40   import org.apache.catalina.Context;
   41   import org.apache.catalina.Manager;
   42   import org.apache.catalina.Session;
   43   import org.apache.catalina.manager.util.BaseSessionComparator;
   44   import org.apache.catalina.manager.util.ReverseComparator;
   45   import org.apache.catalina.manager.util.SessionUtils;
   46   import org.apache.catalina.util.RequestUtil;
   47   import org.apache.catalina.util.ServerInfo;
   48   import org.apache.tomcat.util.http.fileupload.DiskFileUpload;
   49   import org.apache.tomcat.util.http.fileupload.FileItem;
   50   
   51   /**
   52   * Servlet that enables remote management of the web applications deployed
   53   * within the same virtual host as this web application is.  Normally, this
   54   * functionality will be protected by a security constraint in the web
   55   * application deployment descriptor.  However, this requirement can be
   56   * relaxed during testing.
   57   * <p>
   58   * The difference between the <code>ManagerServlet</code> and this
   59   * Servlet is that this Servlet prints out a HTML interface which
   60   * makes it easier to administrate.
   61   * <p>
   62   * However if you use a software that parses the output of
   63   * <code>ManagerServlet</code> you won't be able to upgrade
   64   * to this Servlet since the output are not in the
   65   * same format ar from <code>ManagerServlet</code>
   66   *
   67   * @author Bip Thelin
   68   * @author Malcolm Edgar
   69   * @author Glenn L. Nielsen
   70   * @version $Revision: 612948 $, $Date: 2008-01-17 20:38:25 +0100 (jeu., 17 janv. 2008) $
   71   * @see ManagerServlet
   72   */
   73   
   74   public final class HTMLManagerServlet extends ManagerServlet {
   75   
   76       protected static final String APPLICATION_MESSAGE = "message";
   77       protected static final String APPLICATION_ERROR = "error";
   78       protected String sessionsListJspPath  = "/sessionsList.jsp";
   79       protected String sessionDetailJspPath = "/sessionDetail.jsp";
   80   
   81       // --------------------------------------------------------- Public Methods
   82   
   83       /**
   84        * Process a GET request for the specified resource.
   85        *
   86        * @param request The servlet request we are processing
   87        * @param response The servlet response we are creating
   88        *
   89        * @exception IOException if an input/output error occurs
   90        * @exception ServletException if a servlet-specified error occurs
   91        */
   92       public void doGet(HttpServletRequest request,
   93                         HttpServletResponse response)
   94           throws IOException, ServletException {
   95   
   96           // Identify the request parameters that we need
   97           String command = request.getPathInfo();
   98   
   99           String path = request.getParameter("path");
  100           String deployPath = request.getParameter("deployPath");
  101           String deployConfig = request.getParameter("deployConfig");
  102           String deployWar = request.getParameter("deployWar");
  103   
  104           // Prepare our output writer to generate the response message
  105           response.setContentType("text/html; charset=" + Constants.CHARSET);
  106   
  107           String message = "";
  108           // Process the requested command
  109           if (command == null || command.equals("/")) {
  110           } else if (command.equals("/deploy")) {
  111               message = deployInternal(deployConfig, deployPath, deployWar);
  112           } else if (command.equals("/list")) {
  113           } else if (command.equals("/reload")) {
  114               message = reload(path);
  115           } else if (command.equals("/undeploy")) {
  116               message = undeploy(path);
  117           } else if (command.equals("/expire")) {
  118               message = expireSessions(path, request);
  119           } else if (command.equals("/sessions")) {
  120               try {
  121                   doSessions(path, request, response);
  122                   return;
  123               } catch (Exception e) {
  124                   log("HTMLManagerServlet.sessions[" + path + "]", e);
  125                   message = sm.getString("managerServlet.exception",
  126                           e.toString());
  127               }
  128           } else if (command.equals("/start")) {
  129               message = start(path);
  130           } else if (command.equals("/stop")) {
  131               message = stop(path);
  132           } else {
  133               message =
  134                   sm.getString("managerServlet.unknownCommand", command);
  135           }
  136   
  137           list(request, response, message);
  138       }
  139   
  140       /**
  141        * Process a POST request for the specified resource.
  142        *
  143        * @param request The servlet request we are processing
  144        * @param response The servlet response we are creating
  145        *
  146        * @exception IOException if an input/output error occurs
  147        * @exception ServletException if a servlet-specified error occurs
  148        */
  149       public void doPost(HttpServletRequest request,
  150                         HttpServletResponse response)
  151           throws IOException, ServletException {
  152   
  153           // Identify the request parameters that we need
  154           String command = request.getPathInfo();
  155   
  156           if (command == null || !command.equals("/upload")) {
  157               doGet(request,response);
  158               return;
  159           }
  160   
  161           // Prepare our output writer to generate the response message
  162           response.setContentType("text/html; charset=" + Constants.CHARSET);
  163   
  164           String message = "";
  165   
  166           // Create a new file upload handler
  167           DiskFileUpload upload = new DiskFileUpload();
  168   
  169           // Get the tempdir
  170           File tempdir = (File) getServletContext().getAttribute
  171               ("javax.servlet.context.tempdir");
  172           // Set upload parameters
  173           upload.setSizeMax(-1);
  174           upload.setRepositoryPath(tempdir.getCanonicalPath());
  175       
  176           // Parse the request
  177           String basename = null;
  178           String war = null;
  179           FileItem warUpload = null;
  180           try {
  181               List items = upload.parseRequest(request);
  182           
  183               // Process the uploaded fields
  184               Iterator iter = items.iterator();
  185               while (iter.hasNext()) {
  186                   FileItem item = (FileItem) iter.next();
  187           
  188                   if (!item.isFormField()) {
  189                       if (item.getFieldName().equals("deployWar") &&
  190                           warUpload == null) {
  191                           warUpload = item;
  192                       } else {
  193                           item.delete();
  194                       }
  195                   }
  196               }
  197               while (true) {
  198                   if (warUpload == null) {
  199                       message = sm.getString
  200                           ("htmlManagerServlet.deployUploadNoFile");
  201                       break;
  202                   }
  203                   war = warUpload.getName();
  204                   if (!war.toLowerCase().endsWith(".war")) {
  205                       message = sm.getString
  206                           ("htmlManagerServlet.deployUploadNotWar",war);
  207                       break;
  208                   }
  209                   // Get the filename if uploaded name includes a path
  210                   if (war.lastIndexOf('\\') >= 0) {
  211                       war = war.substring(war.lastIndexOf('\\') + 1);
  212                   }
  213                   if (war.lastIndexOf('/') >= 0) {
  214                       war = war.substring(war.lastIndexOf('/') + 1);
  215                   }
  216                   // Identify the appBase of the owning Host of this Context
  217                   // (if any)
  218                   basename = war.substring(0, war.toLowerCase().indexOf(".war"));
  219                   File file = new File(getAppBase(), war);
  220                   if (file.exists()) {
  221                       message = sm.getString
  222                           ("htmlManagerServlet.deployUploadWarExists",war);
  223                       break;
  224                   }
  225                   String path = null;
  226                   if (basename.equals("ROOT")) {
  227                       path = "";
  228                   } else {
  229                       path = "/" + basename;
  230                   }
  231   
  232                   if ((host.findChild(path) != null) && !isDeployed(path)) {
  233                       message = sm.getString
  234                           ("htmlManagerServlet.deployUploadInServerXml", war);
  235                       break;
  236                   }
  237   
  238                   if (!isServiced(path)) {
  239                       addServiced(path);
  240                       try {
  241                           warUpload.write(file);
  242                           // Perform new deployment
  243                           check(path);
  244                       } finally {
  245                           removeServiced(path);
  246                       }
  247                   }
  248                   break;
  249               }
  250           } catch(Exception e) {
  251               message = sm.getString
  252                   ("htmlManagerServlet.deployUploadFail", e.getMessage());
  253               log(message, e);
  254           } finally {
  255               if (warUpload != null) {
  256                   warUpload.delete();
  257               }
  258               warUpload = null;
  259           }
  260   
  261           list(request, response, message);
  262       }
  263   
  264       /**
  265        * Deploy an application for the specified path from the specified
  266        * web application archive.
  267        *
  268        * @param config URL of the context configuration file to be deployed
  269        * @param path Context path of the application to be deployed
  270        * @param war URL of the web application archive to be deployed
  271        * @return message String
  272        */
  273       protected String deployInternal(String config, String path, String war) {
  274   
  275           StringWriter stringWriter = new StringWriter();
  276           PrintWriter printWriter = new PrintWriter(stringWriter);
  277   
  278           super.deploy(printWriter, config, path, war, false);
  279   
  280           return stringWriter.toString();
  281       }
  282   
  283       /**
  284        * Render a HTML list of the currently active Contexts in our virtual host,
  285        * and memory and server status information.
  286        *
  287        * @param request The request
  288        * @param response The response
  289        * @param message a message to display
  290        */
  291       public void list(HttpServletRequest request,
  292                        HttpServletResponse response,
  293                        String message) throws IOException {
  294   
  295           if (debug >= 1)
  296               log("list: Listing contexts for virtual host '" +
  297                   host.getName() + "'");
  298   
  299           PrintWriter writer = response.getWriter();
  300   
  301           // HTML Header Section
  302           writer.print(Constants.HTML_HEADER_SECTION);
  303   
  304           // Body Header Section
  305           Object[] args = new Object[2];
  306           args[0] = request.getContextPath();
  307           args[1] = sm.getString("htmlManagerServlet.title");
  308           writer.print(MessageFormat.format
  309                        (Constants.BODY_HEADER_SECTION, args));
  310   
  311           // Message Section
  312           args = new Object[3];
  313           args[0] = sm.getString("htmlManagerServlet.messageLabel");
  314           if (message == null || message.length() == 0) {
  315               args[1] = "OK";
  316           } else {
  317               args[1] = RequestUtil.filter(message);
  318           }
  319           writer.print(MessageFormat.format(Constants.MESSAGE_SECTION, args));
  320   
  321           // Manager Section
  322           args = new Object[9];
  323           args[0] = sm.getString("htmlManagerServlet.manager");
  324           args[1] = response.encodeURL(request.getContextPath() + "/html/list");
  325           args[2] = sm.getString("htmlManagerServlet.list");
  326           args[3] = response.encodeURL
  327               (request.getContextPath() + "/" +
  328                sm.getString("htmlManagerServlet.helpHtmlManagerFile"));
  329           args[4] = sm.getString("htmlManagerServlet.helpHtmlManager");
  330           args[5] = response.encodeURL
  331               (request.getContextPath() + "/" +
  332                sm.getString("htmlManagerServlet.helpManagerFile"));
  333           args[6] = sm.getString("htmlManagerServlet.helpManager");
  334           args[7] = response.encodeURL
  335               (request.getContextPath() + "/status");
  336           args[8] = sm.getString("statusServlet.title");
  337           writer.print(MessageFormat.format(Constants.MANAGER_SECTION, args));
  338   
  339           // Apps Header Section
  340           args = new Object[6];
  341           args[0] = sm.getString("htmlManagerServlet.appsTitle");
  342           args[1] = sm.getString("htmlManagerServlet.appsPath");
  343           args[2] = sm.getString("htmlManagerServlet.appsName");
  344           args[3] = sm.getString("htmlManagerServlet.appsAvailable");
  345           args[4] = sm.getString("htmlManagerServlet.appsSessions");
  346           args[5] = sm.getString("htmlManagerServlet.appsTasks");
  347           writer.print(MessageFormat.format(APPS_HEADER_SECTION, args));
  348   
  349           // Apps Row Section
  350           // Create sorted map of deployed applications context paths.
  351           Container children[] = host.findChildren();
  352           String contextPaths[] = new String[children.length];
  353           for (int i = 0; i < children.length; i++)
  354               contextPaths[i] = children[i].getName();
  355   
  356           TreeMap sortedContextPathsMap = new TreeMap();
  357   
  358           for (int i = 0; i < contextPaths.length; i++) {
  359               String displayPath = contextPaths[i];
  360               sortedContextPathsMap.put(displayPath, contextPaths[i]);
  361           }
  362   
  363           String appsStart = sm.getString("htmlManagerServlet.appsStart");
  364           String appsStop = sm.getString("htmlManagerServlet.appsStop");
  365           String appsReload = sm.getString("htmlManagerServlet.appsReload");
  366           String appsUndeploy = sm.getString("htmlManagerServlet.appsUndeploy");
  367           String appsExpire = sm.getString("htmlManagerServlet.appsExpire");
  368   
  369           Iterator iterator = sortedContextPathsMap.entrySet().iterator();
  370           boolean isHighlighted = true;
  371           boolean isDeployed = true;
  372           String highlightColor = null;
  373   
  374           while (iterator.hasNext()) {
  375               // Bugzilla 34818, alternating row colors
  376               isHighlighted = !isHighlighted;
  377               if(isHighlighted) {
  378                   highlightColor = "#C3F3C3";
  379               } else {
  380                   highlightColor = "#FFFFFF";
  381               }
  382   
  383               Map.Entry entry = (Map.Entry) iterator.next();
  384               String displayPath = (String) entry.getKey();
  385               String contextPath = (String) entry.getValue();
  386               Context context = (Context) host.findChild(contextPath);
  387               if (displayPath.equals("")) {
  388                   displayPath = "/";
  389               }
  390   
  391               if (context != null ) {
  392                   try {
  393                       isDeployed = isDeployed(contextPath);
  394                   } catch (Exception e) {
  395                       // Assume false on failure for safety
  396                       isDeployed = false;
  397                   }
  398                   
  399                   args = new Object[6];
  400                   args[0] = displayPath;
  401                   args[1] = context.getDisplayName();
  402                   if (args[1] == null) {
  403                       args[1] = "&nbsp;";
  404                   }
  405                   args[2] = new Boolean(context.getAvailable());
  406                   args[3] = response.encodeURL
  407                       (request.getContextPath() +
  408                        "/html/sessions?path=" + displayPath);
  409                   if (context.getManager() != null) {
  410                       args[4] = new Integer
  411                           (context.getManager().getActiveSessions());
  412                   } else {
  413                       args[4] = new Integer(0);
  414                   }
  415   
  416                   args[5] = highlightColor;
  417   
  418                   writer.print
  419                       (MessageFormat.format(APPS_ROW_DETAILS_SECTION, args));
  420   
  421                   args = new Object[14];
  422                   args[0] = response.encodeURL
  423                       (request.getContextPath() +
  424                        "/html/start?path=" + displayPath);
  425                   args[1] = appsStart;
  426                   args[2] = response.encodeURL
  427                       (request.getContextPath() +
  428                        "/html/stop?path=" + displayPath);
  429                   args[3] = appsStop;
  430                   args[4] = response.encodeURL
  431                       (request.getContextPath() +
  432                        "/html/reload?path=" + displayPath);
  433                   args[5] = appsReload;
  434                   args[6] = response.encodeURL
  435                       (request.getContextPath() +
  436                        "/html/undeploy?path=" + displayPath);
  437                   args[7] = appsUndeploy;
  438                   
  439                   args[8] = response.encodeURL
  440                       (request.getContextPath() +
  441                        "/html/expire?path=" + displayPath);
  442                   args[9] = appsExpire;
  443                   args[10] = sm.getString("htmlManagerServlet.expire.explain");
  444                   Manager manager = context.getManager();
  445                   if (manager == null) {
  446                       args[11] = sm.getString("htmlManagerServlet.noManager");
  447                   } else {
  448                       args[11] = new Integer(
  449                               context.getManager().getMaxInactiveInterval()/60);
  450                   }
  451                   args[12] = sm.getString("htmlManagerServlet.expire.unit");
  452                   
  453                   args[13] = highlightColor;
  454   
  455                   if (context.getPath().equals(this.context.getPath())) {
  456                       writer.print(MessageFormat.format(
  457                           MANAGER_APP_ROW_BUTTON_SECTION, args));
  458                   } else if (context.getAvailable() && isDeployed) {
  459                       writer.print(MessageFormat.format(
  460                           STARTED_DEPLOYED_APPS_ROW_BUTTON_SECTION, args));
  461                   } else if (context.getAvailable() && !isDeployed) {
  462                       writer.print(MessageFormat.format(
  463                           STARTED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION, args));
  464                   } else if (!context.getAvailable() && isDeployed) {
  465                       writer.print(MessageFormat.format(
  466                           STOPPED_DEPLOYED_APPS_ROW_BUTTON_SECTION, args));
  467                   } else {
  468                       writer.print(MessageFormat.format(
  469                           STOPPED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION, args));
  470                   }
  471   
  472               }
  473           }
  474   
  475           // Deploy Section
  476           args = new Object[7];
  477           args[0] = sm.getString("htmlManagerServlet.deployTitle");
  478           args[1] = sm.getString("htmlManagerServlet.deployServer");
  479           args[2] = response.encodeURL(request.getContextPath() + "/html/deploy");
  480           args[3] = sm.getString("htmlManagerServlet.deployPath");
  481           args[4] = sm.getString("htmlManagerServlet.deployConfig");
  482           args[5] = sm.getString("htmlManagerServlet.deployWar");
  483           args[6] = sm.getString("htmlManagerServlet.deployButton");
  484           writer.print(MessageFormat.format(DEPLOY_SECTION, args));
  485   
  486           args = new Object[4];
  487           args[0] = sm.getString("htmlManagerServlet.deployUpload");
  488           args[1] = response.encodeURL(request.getContextPath() + "/html/upload");
  489           args[2] = sm.getString("htmlManagerServlet.deployUploadFile");
  490           args[3] = sm.getString("htmlManagerServlet.deployButton");
  491           writer.print(MessageFormat.format(UPLOAD_SECTION, args));
  492   
  493           // Server Header Section
  494           args = new Object[7];
  495           args[0] = sm.getString("htmlManagerServlet.serverTitle");
  496           args[1] = sm.getString("htmlManagerServlet.serverVersion");
  497           args[2] = sm.getString("htmlManagerServlet.serverJVMVersion");
  498           args[3] = sm.getString("htmlManagerServlet.serverJVMVendor");
  499           args[4] = sm.getString("htmlManagerServlet.serverOSName");
  500           args[5] = sm.getString("htmlManagerServlet.serverOSVersion");
  501           args[6] = sm.getString("htmlManagerServlet.serverOSArch");
  502           writer.print(MessageFormat.format
  503                        (Constants.SERVER_HEADER_SECTION, args));
  504   
  505           // Server Row Section
  506           args = new Object[6];
  507           args[0] = ServerInfo.getServerInfo();
  508           args[1] = System.getProperty("java.runtime.version");
  509           args[2] = System.getProperty("java.vm.vendor");
  510           args[3] = System.getProperty("os.name");
  511           args[4] = System.getProperty("os.version");
  512           args[5] = System.getProperty("os.arch");
  513           writer.print(MessageFormat.format(Constants.SERVER_ROW_SECTION, args));
  514   
  515           // HTML Tail Section
  516           writer.print(Constants.HTML_TAIL_SECTION);
  517   
  518           // Finish up the response
  519           writer.flush();
  520           writer.close();
  521       }
  522   
  523       /**
  524        * Reload the web application at the specified context path.
  525        *
  526        * @see ManagerServlet#reload(PrintWriter, String)
  527        *
  528        * @param path Context path of the application to be restarted
  529        * @return message String
  530        */
  531       protected String reload(String path) {
  532   
  533           StringWriter stringWriter = new StringWriter();
  534           PrintWriter printWriter = new PrintWriter(stringWriter);
  535   
  536           super.reload(printWriter, path);
  537   
  538           return stringWriter.toString();
  539       }
  540   
  541       /**
  542        * Undeploy the web application at the specified context path.
  543        *
  544        * @see ManagerServlet#undeploy(PrintWriter, String)
  545        *
  546        * @param path Context path of the application to be undeployd
  547        * @return message String
  548        */
  549       protected String undeploy(String path) {
  550   
  551           StringWriter stringWriter = new StringWriter();
  552           PrintWriter printWriter = new PrintWriter(stringWriter);
  553   
  554           super.undeploy(printWriter, path);
  555   
  556           return stringWriter.toString();
  557       }
  558   
  559       /**
  560        * Display session information and invoke list.
  561        *
  562        * @see ManagerServlet#sessions(PrintWriter, String, int)
  563        *
  564        * @param path Context path of the application to list session information
  565        * @param idle Expire all sessions with idle time &ge; idle for this context
  566        * @return message String
  567        */
  568       public String sessions(String path, int idle) {
  569   
  570           StringWriter stringWriter = new StringWriter();
  571           PrintWriter printWriter = new PrintWriter(stringWriter);
  572   
  573           super.sessions(printWriter, path, idle);
  574   
  575           return stringWriter.toString();
  576       }
  577   
  578       /**
  579        * Display session information and invoke list.
  580        *
  581        * @see ManagerServlet#sessions(PrintWriter, String)
  582        *
  583        * @param path Context path of the application to list session information
  584        * @return message String
  585        */
  586       public String sessions(String path) {
  587   
  588           return sessions(path, -1);
  589       }
  590   
  591       /**
  592        * Start the web application at the specified context path.
  593        *
  594        * @see ManagerServlet#start(PrintWriter, String)
  595        *
  596        * @param path Context path of the application to be started
  597        * @return message String
  598        */
  599       public String start(String path) {
  600   
  601           StringWriter stringWriter = new StringWriter();
  602           PrintWriter printWriter = new PrintWriter(stringWriter);
  603   
  604           super.start(printWriter, path);
  605   
  606           return stringWriter.toString();
  607       }
  608   
  609       /**
  610        * Stop the web application at the specified context path.
  611        *
  612        * @see ManagerServlet#stop(PrintWriter, String)
  613        *
  614        * @param path Context path of the application to be stopped
  615        * @return message String
  616        */
  617       protected String stop(String path) {
  618   
  619           StringWriter stringWriter = new StringWriter();
  620           PrintWriter printWriter = new PrintWriter(stringWriter);
  621   
  622           super.stop(printWriter, path);
  623   
  624           return stringWriter.toString();
  625       }
  626   
  627       /**
  628        * @see javax.servlet.Servlet#getServletInfo()
  629        */
  630       public String getServletInfo() {
  631           return "HTMLManagerServlet, Copyright (c) The Apache Software Foundation";
  632       }   
  633       
  634       /**
  635        * @see javax.servlet.GenericServlet#init()
  636        */
  637       public void init() throws ServletException {
  638           super.init();
  639       }   
  640   
  641       // ------------------------------------------------ Sessions administration
  642   
  643       /**
  644        *
  645        * Extract the expiration request parameter
  646        * 
  647        * @param path
  648        * @param req
  649        */
  650       protected String expireSessions(String path, HttpServletRequest req) {
  651           int idle = -1;
  652           String idleParam = req.getParameter("idle");
  653           if (idleParam != null) {
  654               try {
  655                   idle = Integer.parseInt(idleParam);
  656               } catch (NumberFormatException e) {
  657                   log("Could not parse idle parameter to an int: " + idleParam);
  658               }
  659           }
  660           return sessions(path, idle);
  661       }
  662   
  663       /**
  664        * 
  665        * @param req
  666        * @param resp
  667        * @throws ServletException
  668        * @throws IOException 
  669        */
  670       protected void doSessions(String path, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  671           req.setAttribute("path", path);
  672           String action = req.getParameter("action");
  673           if (debug >= 1) {
  674               log("sessions: Session action '" + action + "' for web application at '" + path + "'");
  675           }
  676           if ("sessionDetail".equals(action)) {
  677   	        String sessionId = req.getParameter("sessionId");
  678   	        displaySessionDetailPage(req, resp, path, sessionId);
  679   	        return;
  680           } else if ("invalidateSessions".equals(action)) {
  681               String[] sessionIds = req.getParameterValues("sessionIds");
  682               int i = invalidateSessions(path, sessionIds);
  683               req.setAttribute(APPLICATION_MESSAGE, "" + i + " sessions invalidated.");
  684           } else if ("removeSessionAttribute".equals(action)) {
  685               String sessionId = req.getParameter("sessionId");
  686               String name = req.getParameter("attributeName");
  687               boolean removed = removeSessionAttribute(path, sessionId, name);
  688               String outMessage = removed ? "Session attribute '" + name + "' removed." : "Session did not contain any attribute named '" + name + "'";
  689               req.setAttribute(APPLICATION_MESSAGE, outMessage);
  690               resp.sendRedirect(resp.encodeRedirectURL(req.getRequestURL().append("?path=").append(path).append("&action=sessionDetail&sessionId=").append(sessionId).toString()));
  691               return;
  692           } // else
  693           displaySessionsListPage(path, req, resp);
  694       }
  695   
  696       protected Session[] getSessionsForPath(String path) {
  697           if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
  698               throw new IllegalArgumentException(sm.getString("managerServlet.invalidPath",
  699                                           RequestUtil.filter(path)));
  700           }
  701           String displayPath = path;
  702           if( path.equals("/") )
  703               path = "";
  704           Context context = (Context) host.findChild(path);
  705           if (null == context) {
  706               throw new IllegalArgumentException(sm.getString("managerServlet.noContext",
  707                                           RequestUtil.filter(displayPath)));
  708           }
  709           Session[] sessions = context.getManager().findSessions();
  710           return sessions;
  711       }
  712       protected Session getSessionForPathAndId(String path, String id) throws IOException {
  713           if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
  714               throw new IllegalArgumentException(sm.getString("managerServlet.invalidPath",
  715                                           RequestUtil.filter(path)));
  716           }
  717           String displayPath = path;
  718           if( path.equals("/") )
  719               path = "";
  720           Context context = (Context) host.findChild(path);
  721           if (null == context) {
  722               throw new IllegalArgumentException(sm.getString("managerServlet.noContext",
  723                                           RequestUtil.filter(displayPath)));
  724           }
  725           Session session = context.getManager().findSession(id);
  726           return session;
  727       }
  728   
  729       /**
  730        * 
  731        * @param req
  732        * @param resp
  733        * @throws ServletException
  734        * @throws IOException
  735        */
  736       protected void displaySessionsListPage(String path, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  737           List/*<Session>*/ activeSessions = Arrays.asList(getSessionsForPath(path));
  738           String sortBy = req.getParameter("sort");
  739           String orderBy = null;
  740           if (null != sortBy && !"".equals(sortBy.trim())) {
  741               Comparator comparator = getComparator(sortBy);
  742               if (comparator != null) {
  743                   orderBy = req.getParameter("order");
  744                   if ("DESC".equalsIgnoreCase(orderBy)) {
  745                       comparator = new ReverseComparator(comparator);
  746                       // orderBy = "ASC";
  747                   } else {
  748                       //orderBy = "DESC";
  749                   }
  750                   try {
  751   					Collections.sort(activeSessions, comparator);
  752   				} catch (IllegalStateException ise) {
  753   					// at least 1 of the sessions is invalidated
  754   					req.setAttribute(APPLICATION_ERROR, "Can't sort session list: one session is invalidated");
  755   				}
  756               } else {
  757                   log("WARNING: unknown sort order: " + sortBy);
  758               }
  759           }
  760           // keep sort order
  761           req.setAttribute("sort", sortBy);
  762           req.setAttribute("order", orderBy);
  763           req.setAttribute("activeSessions", activeSessions);
  764           //strong>NOTE</strong> - This header will be overridden
  765           // automatically if a <code>RequestDispatcher.forward()</code> call is
  766           // ultimately invoked.
  767           resp.setHeader("Pragma", "No-cache"); // HTTP 1.0
  768           resp.setHeader("Cache-Control", "no-cache,no-store,max-age=0"); // HTTP 1.1
  769           resp.setDateHeader("Expires", 0); // 0 means now
  770           getServletContext().getRequestDispatcher(sessionsListJspPath).include(req, resp);
  771       }
  772   
  773       /**
  774        * 
  775        * @param req
  776        * @param resp
  777        * @throws ServletException
  778        * @throws IOException
  779        */
  780       protected void displaySessionDetailPage(HttpServletRequest req, HttpServletResponse resp, String path, String sessionId) throws ServletException, IOException {
  781           Session session = getSessionForPathAndId(path, sessionId);
  782           //strong>NOTE</strong> - This header will be overridden
  783           // automatically if a <code>RequestDispatcher.forward()</code> call is
  784           // ultimately invoked.
  785           resp.setHeader("Pragma", "No-cache"); // HTTP 1.0
  786           resp.setHeader("Cache-Control", "no-cache,no-store,max-age=0"); // HTTP 1.1
  787           resp.setDateHeader("Expires", 0); // 0 means now
  788           req.setAttribute("currentSession", session);
  789           getServletContext().getRequestDispatcher(sessionDetailJspPath).include(req, resp);
  790       }
  791   
  792       /**
  793        * Invalidate HttpSessions
  794        * @param sessionIds
  795        * @return number of invalidated sessions
  796        * @throws IOException 
  797        */
  798       public int invalidateSessions(String path, String[] sessionIds) throws IOException {
  799           if (null == sessionIds) {
  800               return 0;
  801           }
  802           int nbAffectedSessions = 0;
  803           for (int i = 0; i < sessionIds.length; ++i) {
  804               String sessionId = sessionIds[i];
  805               HttpSession session = getSessionForPathAndId(path, sessionId).getSession();
  806               if (null == session) {
  807                   // Shouldn't happen, but let's play nice...
  808               	if (debug >= 1) {
  809               		log("WARNING: can't invalidate null session " + sessionId);
  810               	}
  811                   continue;
  812               }
  813               try {
  814   				session.invalidate();
  815   				++nbAffectedSessions;
  816   	            if (debug >= 1) {
  817   	                log("Invalidating session id " + sessionId);
  818   	            }
  819   			} catch (IllegalStateException ise) {
  820   				if (debug >= 1) {
  821   					log("Can't invalidate already invalidated session id " + sessionId);
  822   				}
  823   			}
  824           }
  825           return nbAffectedSessions;
  826       }
  827   
  828       /**
  829        * Removes an attribute from an HttpSession
  830        * @param sessionId
  831        * @param attributeName
  832        * @return true if there was an attribute removed, false otherwise
  833        * @throws IOException 
  834        */
  835       public boolean removeSessionAttribute(String path, String sessionId, String attributeName) throws IOException {
  836           HttpSession session = getSessionForPathAndId(path, sessionId).getSession();
  837           if (null == session) {
  838               // Shouldn't happen, but let's play nice...
  839           	if (debug >= 1) {
  840           		log("WARNING: can't remove attribute '" + attributeName + "' for null session " + sessionId);
  841           	}
  842               return false;
  843           }
  844           boolean wasPresent = (null != session.getAttribute(attributeName));
  845           try {
  846               session.removeAttribute(attributeName);
  847           } catch (IllegalStateException ise) {
  848           	if (debug >= 1) {
  849           		log("Can't remote attribute '" + attributeName + "' for invalidated session id " + sessionId);
  850           	}
  851           }
  852           return wasPresent;
  853       }
  854   
  855       /**
  856        * Sets the maximum inactive interval (session timeout) an HttpSession
  857        * @param sessionId
  858        * @param maxInactiveInterval in seconds
  859        * @return old value for maxInactiveInterval
  860        * @throws IOException 
  861        */
  862       public int setSessionMaxInactiveInterval(String path, String sessionId, int maxInactiveInterval) throws IOException {
  863           HttpSession session = getSessionForPathAndId(path, sessionId).getSession();
  864           if (null == session) {
  865               // Shouldn't happen, but let's play nice...
  866           	if (debug >= 1) {
  867           		log("WARNING: can't set timout for null session " + sessionId);
  868           	}
  869               return 0;
  870           }
  871           try {
  872   			int oldMaxInactiveInterval = session.getMaxInactiveInterval();
  873   			session.setMaxInactiveInterval(maxInactiveInterval);
  874   			return oldMaxInactiveInterval;
  875           } catch (IllegalStateException ise) {
  876           	if (debug >= 1) {
  877           		log("Can't set MaxInactiveInterval '" + maxInactiveInterval + "' for invalidated session id " + sessionId);
  878           	}
  879           	return 0;
  880   		}
  881       }
  882   
  883       protected Comparator getComparator(String sortBy) {
  884           Comparator comparator = null;
  885           if ("CreationTime".equalsIgnoreCase(sortBy)) {
  886               comparator = new BaseSessionComparator() {
  887                   public Comparable getComparableObject(Session session) {
  888                       return new Date(session.getCreationTime());
  889                   }
  890               };
  891           } else if ("id".equalsIgnoreCase(sortBy)) {
  892               comparator = new BaseSessionComparator() {
  893                   public Comparable getComparableObject(Session session) {
  894                       return session.getId();
  895                   }
  896               };
  897           } else if ("LastAccessedTime".equalsIgnoreCase(sortBy)) {
  898               comparator = new BaseSessionComparator() {
  899                   public Comparable getComparableObject(Session session) {
  900                       return new Date(session.getLastAccessedTime());
  901                   }
  902               };
  903           } else if ("MaxInactiveInterval".equalsIgnoreCase(sortBy)) {
  904               comparator = new BaseSessionComparator() {
  905                   public Comparable getComparableObject(Session session) {
  906                       return new Date(session.getMaxInactiveInterval());
  907                   }
  908               };
  909           } else if ("new".equalsIgnoreCase(sortBy)) {
  910               comparator = new BaseSessionComparator() {
  911                   public Comparable getComparableObject(Session session) {
  912                       return Boolean.valueOf(session.getSession().isNew());
  913                   }
  914               };
  915           } else if ("locale".equalsIgnoreCase(sortBy)) {
  916               comparator = new BaseSessionComparator() {
  917                   public Comparable getComparableObject(Session session) {
  918                       return JspHelper.guessDisplayLocaleFromSession(session);
  919                   }
  920               };
  921           } else if ("user".equalsIgnoreCase(sortBy)) {
  922               comparator = new BaseSessionComparator() {
  923                   public Comparable getComparableObject(Session session) {
  924                       return JspHelper.guessDisplayUserFromSession(session);
  925                   }
  926               };
  927           } else if ("UsedTime".equalsIgnoreCase(sortBy)) {
  928               comparator = new BaseSessionComparator() {
  929                   public Comparable getComparableObject(Session session) {
  930                       return new Date(SessionUtils.getUsedTimeForSession(session));
  931                   }
  932               };
  933           } else if ("InactiveTime".equalsIgnoreCase(sortBy)) {
  934               comparator = new BaseSessionComparator() {
  935                   public Comparable getComparableObject(Session session) {
  936                       return new Date(SessionUtils.getInactiveTimeForSession(session));
  937                   }
  938               };
  939           } else if ("TTL".equalsIgnoreCase(sortBy)) {
  940               comparator = new BaseSessionComparator() {
  941                   public Comparable getComparableObject(Session session) {
  942                       return new Date(SessionUtils.getTTLForSession(session));
  943                   }
  944               };
  945           }
  946           //TODO: complete this to TTL, etc.
  947           return comparator;
  948       }
  949   
  950       // ------------------------------------------------------ Private Constants
  951   
  952       // These HTML sections are broken in relatively small sections, because of
  953       // limited number of subsitutions MessageFormat can process
  954       // (maximium of 10).
  955   
  956       private static final String APPS_HEADER_SECTION =
  957           "<table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n" +
  958           "<tr>\n" +
  959           " <td colspan=\"5\" class=\"title\">{0}</td>\n" +
  960           "</tr>\n" +
  961           "<tr>\n" +
  962           " <td class=\"header-left\"><small>{1}</small></td>\n" +
  963           " <td class=\"header-left\"><small>{2}</small></td>\n" +
  964           " <td class=\"header-center\"><small>{3}</small></td>\n" +
  965           " <td class=\"header-center\"><small>{4}</small></td>\n" +
  966           " <td class=\"header-left\"><small>{5}</small></td>\n" +
  967           "</tr>\n";
  968   
  969       private static final String APPS_ROW_DETAILS_SECTION =
  970           "<tr>\n" +
  971           " <td class=\"row-left\" bgcolor=\"{5}\" rowspan=\"2\"><small><a href=\"{0}\">{0}</a>" +
  972           "</small></td>\n" +
  973           " <td class=\"row-left\" bgcolor=\"{5}\" rowspan=\"2\"><small>{1}</small></td>\n" +
  974           " <td class=\"row-center\" bgcolor=\"{5}\" rowspan=\"2\"><small>{2}</small></td>\n" +
  975           " <td class=\"row-center\" bgcolor=\"{5}\" rowspan=\"2\">" +
  976           "<small><a href=\"{3}\" target=\"_new\">{4}</a></small></td>\n";
  977   
  978       private static final String MANAGER_APP_ROW_BUTTON_SECTION =
  979           " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
  980           "  <small>\n" +
  981           "  &nbsp;{1}&nbsp;\n" +
  982           "  &nbsp;{3}&nbsp;\n" +
  983           "  &nbsp;{5}&nbsp;\n" +
  984           "  &nbsp;{7}&nbsp;\n" +
  985           "  </small>\n" +
  986           " </td>\n" +
  987           "</tr><tr>\n" +
  988           " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
  989           "  <form method=\"POST\" action=\"{8}\">\n" +
  990           "  <small>\n" +
  991           "  &nbsp;<input type=\"submit\" value=\"{9}\">&nbsp;{10}&nbsp;<input type=\"text\" name=\"idle\" size=\"5\" value=\"{11}\">&nbsp;{12}&nbsp;\n" +
  992           "  </small>\n" +
  993           "  </form>\n" +
  994           " </td>\n" +
  995           "</tr>\n";
  996   
  997       private static final String STARTED_DEPLOYED_APPS_ROW_BUTTON_SECTION =
  998           " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
  999           "  <small>\n" +
 1000           "  &nbsp;{1}&nbsp;\n" +
 1001           "  &nbsp;<a href=\"{2}\" onclick=\"return(confirm('''Are you sure?'''))\">{3}</a>&nbsp;\n" +
 1002           "  &nbsp;<a href=\"{4}\" onclick=\"return(confirm('''Are you sure?'''))\">{5}</a>&nbsp;\n" +
 1003           "  &nbsp;<a href=\"{6}\" onclick=\"return(confirm('''Are you sure?'''))\">{7}</a>&nbsp;\n" +
 1004           "  </small>\n" +
 1005           " </td>\n" +
 1006           " </tr><tr>\n" +
 1007           " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
 1008           "  <form method=\"POST\" action=\"{8}\">\n" +
 1009           "  <small>\n" +
 1010           "  &nbsp;<input type=\"submit\" value=\"{9}\">&nbsp;{10}&nbsp;<input type=\"text\" name=\"idle\" size=\"5\" value=\"{11}\">&nbsp;{12}&nbsp;\n" +
 1011           "  </small>\n" +
 1012           "  </form>\n" +
 1013           " </td>\n" +
 1014           "</tr>\n";
 1015   
 1016       private static final String STOPPED_DEPLOYED_APPS_ROW_BUTTON_SECTION =
 1017           " <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" +
 1018           "  <small>\n" +
 1019           "  &nbsp;<a href=\"{0}\" onclick=\"return(confirm('''Are you sure?'''))\">{1}</a>&nbsp;\n" +
 1020           "  &nbsp;{3}&nbsp;\n" +
 1021           "  &nbsp;{5}&nbsp;\n" +
 1022           "  &nbsp;<a href=\"{6}\" onclick=\"return(confirm('''Are you sure?  This will delete the application.'''))\">{7}</a>&nbsp;\n" +
 1023           "  </small>\n" +
 1024           " </td>\n" +
 1025           "</tr>\n<tr></tr>\n";
 1026   
 1027       private static final String STARTED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION =
 1028           " <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" +
 1029           "  <small>\n" +
 1030           "  &nbsp;{1}&nbsp;\n" +
 1031           "  &nbsp;<a href=\"{2}\" onclick=\"return(confirm('''Are you sure?'''))\">{3}</a>&nbsp;\n" +
 1032           "  &nbsp;<a href=\"{4}\" onclick=\"return(confirm('''Are you sure?'''))\">{5}</a>&nbsp;\n" +
 1033           "  &nbsp;{7}&nbsp;\n" +
 1034           "  </small>\n" +
 1035           " </td>\n" +
 1036           "</tr>\n<tr></tr>\n";
 1037   
 1038       private static final String STOPPED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION =
 1039           " <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" +
 1040           "  <small>\n" +
 1041           "  &nbsp;<a href=\"{0}\" onclick=\"return(confirm('''Are you sure?'''))\">{1}</a>&nbsp;\n" +
 1042           "  &nbsp;{3}&nbsp;\n" +
 1043           "  &nbsp;{5}&nbsp;\n" +
 1044           "  &nbsp;{7}&nbsp;\n" +
 1045           "  </small>\n" +
 1046           " </td>\n" +
 1047           "</tr>\n<tr></tr>\n";
 1048   
 1049       private static final String DEPLOY_SECTION =
 1050           "</table>\n" +
 1051           "<br>\n" +
 1052           "<table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n" +
 1053           "<tr>\n" +
 1054           " <td colspan=\"2\" class=\"title\">{0}</td>\n" +
 1055           "</tr>\n" +
 1056           "<tr>\n" +
 1057           " <td colspan=\"2\" class=\"header-left\"><small>{1}</small></td>\n" +
 1058           "</tr>\n" +
 1059           "<tr>\n" +
 1060           " <td colspan=\"2\">\n" +
 1061           "<form method=\"get\" action=\"{2}\">\n" +
 1062           "<table cellspacing=\"0\" cellpadding=\"3\">\n" +
 1063           "<tr>\n" +
 1064           " <td class=\"row-right\">\n" +
 1065           "  <small>{3}</small>\n" +
 1066           " </td>\n" +
 1067           " <td class=\"row-left\">\n" +
 1068           "  <input type=\"text\" name=\"deployPath\" size=\"20\">\n" +
 1069           " </td>\n" +
 1070           "</tr>\n" +
 1071           "<tr>\n" +
 1072           " <td class=\"row-right\">\n" +
 1073           "  <small>{4}</small>\n" +
 1074           " </td>\n" +
 1075           " <td class=\"row-left\">\n" +
 1076           "  <input type=\"text\" name=\"deployConfig\" size=\"20\">\n" +
 1077           " </td>\n" +
 1078           "</tr>\n" +
 1079           "<tr>\n" +
 1080           " <td class=\"row-right\">\n" +
 1081           "  <small>{5}</small>\n" +
 1082           " </td>\n" +
 1083           " <td class=\"row-left\">\n" +
 1084           "  <input type=\"text\" name=\"deployWar\" size=\"40\">\n" +
 1085           " </td>\n" +
 1086           "</tr>\n" +
 1087           "<tr>\n" +
 1088           " <td class=\"row-right\">\n" +
 1089           "  &nbsp;\n" +
 1090           " </td>\n" +
 1091           " <td class=\"row-left\">\n" +
 1092           "  <input type=\"submit\" value=\"{6}\">\n" +
 1093           " </td>\n" +
 1094           "</tr>\n" +
 1095           "</table>\n" +
 1096           "</form>\n" +
 1097           "</td>\n" +
 1098           "</tr>\n";
 1099   
 1100       private static final String UPLOAD_SECTION =
 1101           "<tr>\n" +
 1102           " <td colspan=\"2\" class=\"header-left\"><small>{0}</small></td>\n" +
 1103           "</tr>\n" +
 1104           "<tr>\n" +
 1105           " <td colspan=\"2\">\n" +
 1106           "<form action=\"{1}\" method=\"post\" " +
 1107           "enctype=\"multipart/form-data\">\n" +
 1108           "<table cellspacing=\"0\" cellpadding=\"3\">\n" +
 1109           "<tr>\n" +
 1110           " <td class=\"row-right\">\n" +
 1111           "  <small>{2}</small>\n" +
 1112           " </td>\n" +
 1113           " <td class=\"row-left\">\n" +
 1114           "  <input type=\"file\" name=\"deployWar\" size=\"40\">\n" +
 1115           " </td>\n" +
 1116           "</tr>\n" +
 1117           "<tr>\n" +
 1118           " <td class=\"row-right\">\n" +
 1119           "  &nbsp;\n" +
 1120           " </td>\n" +
 1121           " <td class=\"row-left\">\n" +
 1122           "  <input type=\"submit\" value=\"{3}\">\n" +
 1123           " </td>\n" +
 1124           "</tr>\n" +
 1125           "</table>\n" +
 1126           "</form>\n" +
 1127           "</table>\n" +
 1128           "<br>\n" +
 1129           "\n";
 1130   
 1131   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » manager » [javadoc | source]